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 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 int x86emu_check_jump_condition(u8 op)
74 DECODE_PRINTF("JO\t");
75 return ACCESS_FLAG(F_OF);
77 DECODE_PRINTF("JNO\t");
78 return !ACCESS_FLAG(F_OF);
81 DECODE_PRINTF("JB\t");
82 return ACCESS_FLAG(F_CF);
85 DECODE_PRINTF("JNB\t");
86 return !ACCESS_FLAG(F_CF);
89 DECODE_PRINTF("JZ\t");
90 return ACCESS_FLAG(F_ZF);
93 DECODE_PRINTF("JNZ\t");
94 return !ACCESS_FLAG(F_ZF);
97 DECODE_PRINTF("JBE\t");
98 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
101 DECODE_PRINTF("JNBE\t");
102 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
105 DECODE_PRINTF("JS\t");
106 return ACCESS_FLAG(F_SF);
109 DECODE_PRINTF("JNS\t");
110 return !ACCESS_FLAG(F_SF);
113 DECODE_PRINTF("JP\t");
114 return ACCESS_FLAG(F_PF);
117 DECODE_PRINTF("JNP\t");
118 return !ACCESS_FLAG(F_PF);
121 DECODE_PRINTF("JL\t");
122 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
125 DECODE_PRINTF("JNL\t");
126 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
129 DECODE_PRINTF("JLE\t");
130 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
134 DECODE_PRINTF("JNLE\t");
135 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
140 void x86emuOp2_long_jump(u8 op2)
145 /* conditional jump to word offset. */
147 cond = x86emu_check_jump_condition(op2 & 0xF);
148 target = (s16) fetch_word_imm();
149 target += (s16) M.x86.R_IP;
150 DECODE_PRINTF2("%04x\n", target);
153 M.x86.R_IP = (u16)target;
154 JMP_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, M.x86.R_IP, " LONG COND ");
156 DECODE_CLEAR_SEGOVR();
160 /****************************************************************************
162 Handles opcode 0x0f,0x90-0x9F
163 ****************************************************************************/
164 void x86emuOp2_set_byte(u8 op2)
176 cond = ACCESS_FLAG(F_OF);
180 cond = !ACCESS_FLAG(F_OF);
184 cond = ACCESS_FLAG(F_CF);
188 cond = !ACCESS_FLAG(F_CF);
192 cond = ACCESS_FLAG(F_ZF);
196 cond = !ACCESS_FLAG(F_ZF);
200 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
204 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
208 cond = ACCESS_FLAG(F_SF);
212 cond = !ACCESS_FLAG(F_SF);
216 cond = ACCESS_FLAG(F_PF);
220 cond = !ACCESS_FLAG(F_PF);
224 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
228 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
232 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
237 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
242 FETCH_DECODE_MODRM(mod, rh, rl);
244 destoffset = decode_rmXX_address(mod, rl);
246 store_data_byte(destoffset, cond ? 0x01 : 0x00);
247 } else { /* register to register */
248 destreg = DECODE_RM_BYTE_REGISTER(rl);
250 *destreg = cond ? 0x01 : 0x00;
252 DECODE_CLEAR_SEGOVR();
256 /****************************************************************************
258 Handles opcode 0x0f,0xa0
259 ****************************************************************************/
260 void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
263 DECODE_PRINTF("PUSH\tFS\n");
265 push_word(M.x86.R_FS);
266 DECODE_CLEAR_SEGOVR();
270 /****************************************************************************
272 Handles opcode 0x0f,0xa1
273 ****************************************************************************/
274 void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
277 DECODE_PRINTF("POP\tFS\n");
279 M.x86.R_FS = pop_word();
280 DECODE_CLEAR_SEGOVR();
284 /****************************************************************************
286 Handles opcode 0x0f,0xa3
287 ****************************************************************************/
288 void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
295 DECODE_PRINTF("BT\t");
296 FETCH_DECODE_MODRM(mod, rh, rl);
298 srcoffset = decode_rmXX_address(mod, rl);
299 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
304 shiftreg = DECODE_RM_LONG_REGISTER(rh);
306 bit = *shiftreg & 0x1F;
307 disp = (s16)*shiftreg >> 5;
308 srcval = fetch_data_long(srcoffset+disp);
309 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
315 shiftreg = DECODE_RM_WORD_REGISTER(rh);
317 bit = *shiftreg & 0xF;
318 disp = (s16)*shiftreg >> 4;
319 srcval = fetch_data_word(srcoffset+disp);
320 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
322 } else { /* register to register */
323 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
324 u32 *srcreg,*shiftreg;
326 srcreg = DECODE_RM_LONG_REGISTER(rl);
328 shiftreg = DECODE_RM_LONG_REGISTER(rh);
330 bit = *shiftreg & 0x1F;
331 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
333 u16 *srcreg,*shiftreg;
335 srcreg = DECODE_RM_WORD_REGISTER(rl);
337 shiftreg = DECODE_RM_WORD_REGISTER(rh);
339 bit = *shiftreg & 0xF;
340 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
343 DECODE_CLEAR_SEGOVR();
347 /****************************************************************************
349 Handles opcode 0x0f,0xa4
350 ****************************************************************************/
351 void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
358 DECODE_PRINTF("SHLD\t");
359 FETCH_DECODE_MODRM(mod, rh, rl);
361 destoffset = decode_rmXX_address(mod, rl);
362 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
367 shiftreg = DECODE_RM_LONG_REGISTER(rh);
369 shift = fetch_byte_imm();
370 DECODE_PRINTF2("%d\n", shift);
372 destval = fetch_data_long(destoffset);
373 destval = shld_long(destval,*shiftreg,shift);
374 store_data_long(destoffset, destval);
380 shiftreg = DECODE_RM_WORD_REGISTER(rh);
382 shift = fetch_byte_imm();
383 DECODE_PRINTF2("%d\n", shift);
385 destval = fetch_data_word(destoffset);
386 destval = shld_word(destval,*shiftreg,shift);
387 store_data_word(destoffset, destval);
389 } else { /* register to register */
390 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
391 u32 *destreg,*shiftreg;
393 destreg = DECODE_RM_LONG_REGISTER(rl);
395 shiftreg = DECODE_RM_LONG_REGISTER(rh);
397 shift = fetch_byte_imm();
398 DECODE_PRINTF2("%d\n", shift);
400 *destreg = shld_long(*destreg,*shiftreg,shift);
402 u16 *destreg,*shiftreg;
404 destreg = DECODE_RM_WORD_REGISTER(rl);
406 shiftreg = DECODE_RM_WORD_REGISTER(rh);
408 shift = fetch_byte_imm();
409 DECODE_PRINTF2("%d\n", shift);
411 *destreg = shld_word(*destreg,*shiftreg,shift);
414 DECODE_CLEAR_SEGOVR();
418 /****************************************************************************
420 Handles opcode 0x0f,0xa5
421 ****************************************************************************/
422 void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
428 DECODE_PRINTF("SHLD\t");
429 FETCH_DECODE_MODRM(mod, rh, rl);
431 destoffset = decode_rmXX_address(mod, rl);
432 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
437 shiftreg = DECODE_RM_LONG_REGISTER(rh);
438 DECODE_PRINTF(",CL\n");
440 destval = fetch_data_long(destoffset);
441 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
442 store_data_long(destoffset, destval);
448 shiftreg = DECODE_RM_WORD_REGISTER(rh);
449 DECODE_PRINTF(",CL\n");
451 destval = fetch_data_word(destoffset);
452 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
453 store_data_word(destoffset, destval);
455 } else { /* register to register */
456 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
457 u32 *destreg,*shiftreg;
459 destreg = DECODE_RM_LONG_REGISTER(rl);
461 shiftreg = DECODE_RM_LONG_REGISTER(rh);
462 DECODE_PRINTF(",CL\n");
464 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
466 u16 *destreg,*shiftreg;
468 destreg = DECODE_RM_WORD_REGISTER(rl);
470 shiftreg = DECODE_RM_WORD_REGISTER(rh);
471 DECODE_PRINTF(",CL\n");
473 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
476 DECODE_CLEAR_SEGOVR();
480 /****************************************************************************
482 Handles opcode 0x0f,0xa8
483 ****************************************************************************/
484 void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
487 DECODE_PRINTF("PUSH\tGS\n");
489 push_word(M.x86.R_GS);
490 DECODE_CLEAR_SEGOVR();
494 /****************************************************************************
496 Handles opcode 0x0f,0xa9
497 ****************************************************************************/
498 void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
501 DECODE_PRINTF("POP\tGS\n");
503 M.x86.R_GS = pop_word();
504 DECODE_CLEAR_SEGOVR();
508 /****************************************************************************
510 Handles opcode 0x0f,0xaa
511 ****************************************************************************/
512 void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
519 DECODE_PRINTF("BTS\t");
520 FETCH_DECODE_MODRM(mod, rh, rl);
522 srcoffset = decode_rmXX_address(mod, rl);
523 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
528 shiftreg = DECODE_RM_LONG_REGISTER(rh);
530 bit = *shiftreg & 0x1F;
531 disp = (s16)*shiftreg >> 5;
532 srcval = fetch_data_long(srcoffset+disp);
534 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
535 store_data_long(srcoffset+disp, srcval | mask);
541 shiftreg = DECODE_RM_WORD_REGISTER(rh);
543 bit = *shiftreg & 0xF;
544 disp = (s16)*shiftreg >> 4;
545 srcval = fetch_data_word(srcoffset+disp);
546 mask = (u16)(0x1 << bit);
547 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
548 store_data_word(srcoffset+disp, srcval | mask);
550 } else { /* register to register */
551 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
552 u32 *srcreg,*shiftreg;
555 srcreg = DECODE_RM_LONG_REGISTER(rl);
557 shiftreg = DECODE_RM_LONG_REGISTER(rh);
559 bit = *shiftreg & 0x1F;
561 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
564 u16 *srcreg,*shiftreg;
567 srcreg = DECODE_RM_WORD_REGISTER(rl);
569 shiftreg = DECODE_RM_WORD_REGISTER(rh);
571 bit = *shiftreg & 0xF;
572 mask = (u16)(0x1 << bit);
573 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
577 DECODE_CLEAR_SEGOVR();
581 /****************************************************************************
583 Handles opcode 0x0f,0xac
584 ****************************************************************************/
585 void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
592 DECODE_PRINTF("SHLD\t");
593 FETCH_DECODE_MODRM(mod, rh, rl);
595 destoffset = decode_rmXX_address(mod, rl);
596 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
601 shiftreg = DECODE_RM_LONG_REGISTER(rh);
603 shift = fetch_byte_imm();
604 DECODE_PRINTF2("%d\n", shift);
606 destval = fetch_data_long(destoffset);
607 destval = shrd_long(destval,*shiftreg,shift);
608 store_data_long(destoffset, destval);
614 shiftreg = DECODE_RM_WORD_REGISTER(rh);
616 shift = fetch_byte_imm();
617 DECODE_PRINTF2("%d\n", shift);
619 destval = fetch_data_word(destoffset);
620 destval = shrd_word(destval,*shiftreg,shift);
621 store_data_word(destoffset, destval);
623 } else { /* register to register */
624 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
625 u32 *destreg,*shiftreg;
627 destreg = DECODE_RM_LONG_REGISTER(rl);
629 shiftreg = DECODE_RM_LONG_REGISTER(rh);
631 shift = fetch_byte_imm();
632 DECODE_PRINTF2("%d\n", shift);
634 *destreg = shrd_long(*destreg,*shiftreg,shift);
636 u16 *destreg,*shiftreg;
638 destreg = DECODE_RM_WORD_REGISTER(rl);
640 shiftreg = DECODE_RM_WORD_REGISTER(rh);
642 shift = fetch_byte_imm();
643 DECODE_PRINTF2("%d\n", shift);
645 *destreg = shrd_word(*destreg,*shiftreg,shift);
648 DECODE_CLEAR_SEGOVR();
652 /****************************************************************************
654 Handles opcode 0x0f,0xad
655 ****************************************************************************/
656 void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
662 DECODE_PRINTF("SHLD\t");
663 FETCH_DECODE_MODRM(mod, rh, rl);
665 destoffset = decode_rmXX_address(mod, rl);
667 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
671 shiftreg = DECODE_RM_LONG_REGISTER(rh);
672 DECODE_PRINTF(",CL\n");
674 destval = fetch_data_long(destoffset);
675 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
676 store_data_long(destoffset, destval);
681 shiftreg = DECODE_RM_WORD_REGISTER(rh);
682 DECODE_PRINTF(",CL\n");
684 destval = fetch_data_word(destoffset);
685 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
686 store_data_word(destoffset, destval);
688 } else { /* register to register */
689 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
690 u32 *destreg,*shiftreg;
692 destreg = DECODE_RM_LONG_REGISTER(rl);
694 shiftreg = DECODE_RM_LONG_REGISTER(rh);
695 DECODE_PRINTF(",CL\n");
697 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
699 u16 *destreg,*shiftreg;
701 destreg = DECODE_RM_WORD_REGISTER(rl);
703 shiftreg = DECODE_RM_WORD_REGISTER(rh);
704 DECODE_PRINTF(",CL\n");
706 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
709 DECODE_CLEAR_SEGOVR();
713 /****************************************************************************
715 Handles opcode 0x0f,0xaf
716 ****************************************************************************/
717 void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
723 DECODE_PRINTF("IMUL\t");
724 FETCH_DECODE_MODRM(mod, rh, rl);
726 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
731 destreg = DECODE_RM_LONG_REGISTER(rh);
733 srcoffset = decode_rmXX_address(mod, rl);
734 srcval = fetch_data_long(srcoffset);
736 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
744 *destreg = (u32)res_lo;
750 destreg = DECODE_RM_WORD_REGISTER(rh);
752 srcoffset = decode_rmXX_address(mod, rl);
753 srcval = fetch_data_word(srcoffset);
755 res = (s16)*destreg * (s16)srcval;
765 } else { /* register to register */
766 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
767 u32 *destreg,*srcreg;
770 destreg = DECODE_RM_LONG_REGISTER(rh);
772 srcreg = DECODE_RM_LONG_REGISTER(rl);
774 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
782 *destreg = (u32)res_lo;
784 u16 *destreg,*srcreg;
787 destreg = DECODE_RM_WORD_REGISTER(rh);
789 srcreg = DECODE_RM_WORD_REGISTER(rl);
790 res = (s16)*destreg * (s16)*srcreg;
801 DECODE_CLEAR_SEGOVR();
805 /****************************************************************************
807 Handles opcode 0x0f,0xb2
808 ****************************************************************************/
809 void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
816 DECODE_PRINTF("LSS\t");
817 FETCH_DECODE_MODRM(mod, rh, rl);
819 dstreg = DECODE_RM_WORD_REGISTER(rh);
821 srcoffset = decode_rmXX_address(mod, rl);
824 *dstreg = fetch_data_word(srcoffset);
825 M.x86.R_SS = fetch_data_word(srcoffset + 2);
826 } else { /* register to register */
830 DECODE_CLEAR_SEGOVR();
834 /****************************************************************************
836 Handles opcode 0x0f,0xb3
837 ****************************************************************************/
838 void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
845 DECODE_PRINTF("BTR\t");
846 FETCH_DECODE_MODRM(mod, rh, rl);
848 srcoffset = decode_rmXX_address(mod, rl);
850 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
854 shiftreg = DECODE_RM_LONG_REGISTER(rh);
856 bit = *shiftreg & 0x1F;
857 disp = (s16)*shiftreg >> 5;
858 srcval = fetch_data_long(srcoffset+disp);
860 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
861 store_data_long(srcoffset+disp, srcval & ~mask);
866 shiftreg = DECODE_RM_WORD_REGISTER(rh);
868 bit = *shiftreg & 0xF;
869 disp = (s16)*shiftreg >> 4;
870 srcval = fetch_data_word(srcoffset+disp);
871 mask = (u16)(0x1 << bit);
872 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
873 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
875 } else { /* register to register */
876 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
877 u32 *srcreg,*shiftreg;
880 srcreg = DECODE_RM_LONG_REGISTER(rl);
882 shiftreg = DECODE_RM_LONG_REGISTER(rh);
884 bit = *shiftreg & 0x1F;
886 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
889 u16 *srcreg,*shiftreg;
892 srcreg = DECODE_RM_WORD_REGISTER(rl);
894 shiftreg = DECODE_RM_WORD_REGISTER(rh);
896 bit = *shiftreg & 0xF;
897 mask = (u16)(0x1 << bit);
898 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
902 DECODE_CLEAR_SEGOVR();
906 /****************************************************************************
908 Handles opcode 0x0f,0xb4
909 ****************************************************************************/
910 void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
917 DECODE_PRINTF("LFS\t");
918 FETCH_DECODE_MODRM(mod, rh, rl);
920 dstreg = DECODE_RM_WORD_REGISTER(rh);
922 srcoffset = decode_rmXX_address(mod, rl);
925 *dstreg = fetch_data_word(srcoffset);
926 M.x86.R_FS = fetch_data_word(srcoffset + 2);
927 } else { /* register to register */
931 DECODE_CLEAR_SEGOVR();
935 /****************************************************************************
937 Handles opcode 0x0f,0xb5
938 ****************************************************************************/
939 void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
946 DECODE_PRINTF("LGS\t");
947 FETCH_DECODE_MODRM(mod, rh, rl);
949 dstreg = DECODE_RM_WORD_REGISTER(rh);
951 srcoffset = decode_rmXX_address(mod, rl);
954 *dstreg = fetch_data_word(srcoffset);
955 M.x86.R_GS = fetch_data_word(srcoffset + 2);
956 } else { /* register to register */
960 DECODE_CLEAR_SEGOVR();
964 /****************************************************************************
966 Handles opcode 0x0f,0xb6
967 ****************************************************************************/
968 void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
974 DECODE_PRINTF("MOVZX\t");
975 FETCH_DECODE_MODRM(mod, rh, rl);
977 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
981 destreg = DECODE_RM_LONG_REGISTER(rh);
983 srcoffset = decode_rmXX_address(mod, rl);
984 srcval = fetch_data_byte(srcoffset);
992 destreg = DECODE_RM_WORD_REGISTER(rh);
994 srcoffset = decode_rmXX_address(mod, rl);
995 srcval = fetch_data_byte(srcoffset);
1000 } else { /* register to register */
1001 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1005 destreg = DECODE_RM_LONG_REGISTER(rh);
1007 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1008 DECODE_PRINTF("\n");
1015 destreg = DECODE_RM_WORD_REGISTER(rh);
1017 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1018 DECODE_PRINTF("\n");
1023 DECODE_CLEAR_SEGOVR();
1027 /****************************************************************************
1029 Handles opcode 0x0f,0xb7
1030 ****************************************************************************/
1031 void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1040 DECODE_PRINTF("MOVZX\t");
1041 FETCH_DECODE_MODRM(mod, rh, rl);
1043 destreg = DECODE_RM_LONG_REGISTER(rh);
1045 srcoffset = decode_rmXX_address(mod, rl);
1046 srcval = fetch_data_word(srcoffset);
1047 DECODE_PRINTF("\n");
1050 } else { /* register to register */
1051 destreg = DECODE_RM_LONG_REGISTER(rh);
1053 srcreg = DECODE_RM_WORD_REGISTER(rl);
1054 DECODE_PRINTF("\n");
1058 DECODE_CLEAR_SEGOVR();
1062 /****************************************************************************
1064 Handles opcode 0x0f,0xba
1065 ****************************************************************************/
1066 void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1074 FETCH_DECODE_MODRM(mod, rh, rl);
1077 DECODE_PRINTF("BT\t");
1080 DECODE_PRINTF("BTS\t");
1083 DECODE_PRINTF("BTR\t");
1086 DECODE_PRINTF("BTC\t");
1089 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1091 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1092 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1097 srcoffset = decode_rmXX_address(mod, rl);
1098 shift = fetch_byte_imm();
1099 DECODE_PRINTF2(",%d\n", shift);
1102 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1106 srcval = fetch_data_long(srcoffset);
1107 mask = (0x1 << bit);
1108 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1111 store_data_long(srcoffset, srcval | mask);
1114 store_data_long(srcoffset, srcval & ~mask);
1117 store_data_long(srcoffset, srcval ^ mask);
1126 srcval = fetch_data_word(srcoffset);
1127 mask = (0x1 << bit);
1128 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1131 store_data_word(srcoffset, srcval | mask);
1134 store_data_word(srcoffset, srcval & ~mask);
1137 store_data_word(srcoffset, srcval ^ mask);
1143 } else { /* register to register */
1144 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1148 srcreg = DECODE_RM_LONG_REGISTER(rl);
1149 shift = fetch_byte_imm();
1150 DECODE_PRINTF2(",%d\n", shift);
1153 mask = (0x1 << bit);
1154 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1172 srcreg = DECODE_RM_WORD_REGISTER(rl);
1173 shift = fetch_byte_imm();
1174 DECODE_PRINTF2(",%d\n", shift);
1177 mask = (0x1 << bit);
1178 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1194 DECODE_CLEAR_SEGOVR();
1198 /****************************************************************************
1200 Handles opcode 0x0f,0xbb
1201 ****************************************************************************/
1202 void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1209 DECODE_PRINTF("BTC\t");
1210 FETCH_DECODE_MODRM(mod, rh, rl);
1212 srcoffset = decode_rmXX_address(mod, rl);
1214 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1218 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1220 bit = *shiftreg & 0x1F;
1221 disp = (s16)*shiftreg >> 5;
1222 srcval = fetch_data_long(srcoffset+disp);
1223 mask = (0x1 << bit);
1224 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1225 store_data_long(srcoffset+disp, srcval ^ mask);
1230 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1232 bit = *shiftreg & 0xF;
1233 disp = (s16)*shiftreg >> 4;
1234 srcval = fetch_data_word(srcoffset+disp);
1235 mask = (u16)(0x1 << bit);
1236 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1237 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1239 } else { /* register to register */
1240 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1241 u32 *srcreg,*shiftreg;
1244 srcreg = DECODE_RM_LONG_REGISTER(rl);
1246 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1248 bit = *shiftreg & 0x1F;
1249 mask = (0x1 << bit);
1250 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1253 u16 *srcreg,*shiftreg;
1256 srcreg = DECODE_RM_WORD_REGISTER(rl);
1258 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1260 bit = *shiftreg & 0xF;
1261 mask = (u16)(0x1 << bit);
1262 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1266 DECODE_CLEAR_SEGOVR();
1270 /****************************************************************************
1272 Handles opcode 0x0f,0xbc
1273 ****************************************************************************/
1274 void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1280 DECODE_PRINTF("BSF\n");
1281 FETCH_DECODE_MODRM(mod, rh, rl);
1283 srcoffset = decode_rmXX_address(mod, rl);
1285 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1286 u32 srcval, *dstreg;
1288 dstreg = DECODE_RM_LONG_REGISTER(rh);
1290 srcval = fetch_data_long(srcoffset);
1291 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1292 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1293 if ((srcval >> *dstreg) & 1) break;
1295 u16 srcval, *dstreg;
1297 dstreg = DECODE_RM_WORD_REGISTER(rh);
1299 srcval = fetch_data_word(srcoffset);
1300 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1301 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1302 if ((srcval >> *dstreg) & 1) break;
1304 } else { /* register to register */
1305 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1306 u32 *srcreg, *dstreg;
1308 srcreg = DECODE_RM_LONG_REGISTER(rl);
1310 dstreg = DECODE_RM_LONG_REGISTER(rh);
1312 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1313 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1314 if ((*srcreg >> *dstreg) & 1) break;
1316 u16 *srcreg, *dstreg;
1318 srcreg = DECODE_RM_WORD_REGISTER(rl);
1320 dstreg = DECODE_RM_WORD_REGISTER(rh);
1322 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1323 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1324 if ((*srcreg >> *dstreg) & 1) break;
1327 DECODE_CLEAR_SEGOVR();
1331 /****************************************************************************
1333 Handles opcode 0x0f,0xbd
1334 ****************************************************************************/
1335 void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1341 DECODE_PRINTF("BSF\n");
1342 FETCH_DECODE_MODRM(mod, rh, rl);
1344 srcoffset = decode_rmXX_address(mod, rl);
1346 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1347 u32 srcval, *dstreg;
1349 dstreg = DECODE_RM_LONG_REGISTER(rh);
1351 srcval = fetch_data_long(srcoffset);
1352 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1353 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1354 if ((srcval >> *dstreg) & 1) break;
1356 u16 srcval, *dstreg;
1358 dstreg = DECODE_RM_WORD_REGISTER(rh);
1360 srcval = fetch_data_word(srcoffset);
1361 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1362 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1363 if ((srcval >> *dstreg) & 1) break;
1365 } else { /* register to register */
1366 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1367 u32 *srcreg, *dstreg;
1369 srcreg = DECODE_RM_LONG_REGISTER(rl);
1371 dstreg = DECODE_RM_LONG_REGISTER(rh);
1373 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1374 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1375 if ((*srcreg >> *dstreg) & 1) break;
1377 u16 *srcreg, *dstreg;
1379 srcreg = DECODE_RM_WORD_REGISTER(rl);
1381 dstreg = DECODE_RM_WORD_REGISTER(rh);
1383 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1384 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1385 if ((*srcreg >> *dstreg) & 1) break;
1388 DECODE_CLEAR_SEGOVR();
1392 /****************************************************************************
1394 Handles opcode 0x0f,0xbe
1395 ****************************************************************************/
1396 void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1402 DECODE_PRINTF("MOVSX\t");
1403 FETCH_DECODE_MODRM(mod, rh, rl);
1405 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1409 destreg = DECODE_RM_LONG_REGISTER(rh);
1411 srcoffset = decode_rmXX_address(mod, rl);
1412 srcval = (s32)((s8)fetch_data_byte(srcoffset));
1413 DECODE_PRINTF("\n");
1420 destreg = DECODE_RM_WORD_REGISTER(rh);
1422 srcoffset = decode_rmXX_address(mod, rl);
1423 srcval = (s16)((s8)fetch_data_byte(srcoffset));
1424 DECODE_PRINTF("\n");
1428 } else { /* register to register */
1429 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1433 destreg = DECODE_RM_LONG_REGISTER(rh);
1435 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1436 DECODE_PRINTF("\n");
1438 *destreg = (s32)((s8)*srcreg);
1443 destreg = DECODE_RM_WORD_REGISTER(rh);
1445 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1446 DECODE_PRINTF("\n");
1448 *destreg = (s16)((s8)*srcreg);
1451 DECODE_CLEAR_SEGOVR();
1455 /****************************************************************************
1457 Handles opcode 0x0f,0xbf
1458 ****************************************************************************/
1459 void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1468 DECODE_PRINTF("MOVSX\t");
1469 FETCH_DECODE_MODRM(mod, rh, rl);
1471 destreg = DECODE_RM_LONG_REGISTER(rh);
1473 srcoffset = decode_rmXX_address(mod, rl);
1474 srcval = (s32)((s16)fetch_data_word(srcoffset));
1475 DECODE_PRINTF("\n");
1478 } else { /* register to register */
1479 destreg = DECODE_RM_LONG_REGISTER(rh);
1481 srcreg = DECODE_RM_WORD_REGISTER(rl);
1482 DECODE_PRINTF("\n");
1484 *destreg = (s32)((s16)*srcreg);
1486 DECODE_CLEAR_SEGOVR();
1490 /****************************************************************************
1492 Handles opcode 0x0f,0xC8-0xCF
1493 ****************************************************************************/
1494 s32 x86emu_bswap(s32 reg)
1496 // perform the byte swap
1498 reg = (temp & 0xFF000000) >> 24;
1499 reg |= (temp & 0xFF0000) >> 8;
1500 reg |= (temp & 0xFF00) << 8;
1501 reg |= (temp & 0xFF) << 24;
1505 void x86emuOp2_bswap(u8 op2)
1507 /* byte swap 32 bit register */
1509 DECODE_PRINTF("BSWAP\t");
1512 DECODE_PRINTF("EAX\n");
1513 M.x86.R_EAX = x86emu_bswap(M.x86.R_EAX);
1516 DECODE_PRINTF("ECX\n");
1517 M.x86.R_ECX = x86emu_bswap(M.x86.R_ECX);
1520 DECODE_PRINTF("EDX\n");
1521 M.x86.R_EDX = x86emu_bswap(M.x86.R_EDX);
1524 DECODE_PRINTF("EBX\n");
1525 M.x86.R_EBX = x86emu_bswap(M.x86.R_EBX);
1528 DECODE_PRINTF("ESP\n");
1529 M.x86.R_ESP = x86emu_bswap(M.x86.R_ESP);
1532 DECODE_PRINTF("EBP\n");
1533 M.x86.R_EBP = x86emu_bswap(M.x86.R_EBP);
1536 DECODE_PRINTF("ESI\n");
1537 M.x86.R_ESI = x86emu_bswap(M.x86.R_ESI);
1540 DECODE_PRINTF("EDI\n");
1541 M.x86.R_EDI = x86emu_bswap(M.x86.R_EDI);
1545 DECODE_CLEAR_SEGOVR();
1549 /***************************************************************************
1550 * Double byte operation code table:
1551 **************************************************************************/
1552 void (*x86emu_optab2[256])(u8) =
1554 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
1555 /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
1556 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
1557 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
1558 /* 0x04 */ x86emuOp2_illegal_op,
1559 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1560 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
1561 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1562 /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
1563 /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
1564 /* 0x0a */ x86emuOp2_illegal_op,
1565 /* 0x0b */ x86emuOp2_illegal_op,
1566 /* 0x0c */ x86emuOp2_illegal_op,
1567 /* 0x0d */ x86emuOp2_illegal_op,
1568 /* 0x0e */ x86emuOp2_illegal_op,
1569 /* 0x0f */ x86emuOp2_illegal_op,
1571 /* 0x10 */ x86emuOp2_illegal_op,
1572 /* 0x11 */ x86emuOp2_illegal_op,
1573 /* 0x12 */ x86emuOp2_illegal_op,
1574 /* 0x13 */ x86emuOp2_illegal_op,
1575 /* 0x14 */ x86emuOp2_illegal_op,
1576 /* 0x15 */ x86emuOp2_illegal_op,
1577 /* 0x16 */ x86emuOp2_illegal_op,
1578 /* 0x17 */ x86emuOp2_illegal_op,
1579 /* 0x18 */ x86emuOp2_illegal_op,
1580 /* 0x19 */ x86emuOp2_illegal_op,
1581 /* 0x1a */ x86emuOp2_illegal_op,
1582 /* 0x1b */ x86emuOp2_illegal_op,
1583 /* 0x1c */ x86emuOp2_illegal_op,
1584 /* 0x1d */ x86emuOp2_illegal_op,
1585 /* 0x1e */ x86emuOp2_illegal_op,
1586 /* 0x1f */ x86emuOp2_illegal_op,
1588 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
1589 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
1590 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
1591 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
1592 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
1593 /* 0x25 */ x86emuOp2_illegal_op,
1594 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
1595 /* 0x27 */ x86emuOp2_illegal_op,
1596 /* 0x28 */ x86emuOp2_illegal_op,
1597 /* 0x29 */ x86emuOp2_illegal_op,
1598 /* 0x2a */ x86emuOp2_illegal_op,
1599 /* 0x2b */ x86emuOp2_illegal_op,
1600 /* 0x2c */ x86emuOp2_illegal_op,
1601 /* 0x2d */ x86emuOp2_illegal_op,
1602 /* 0x2e */ x86emuOp2_illegal_op,
1603 /* 0x2f */ x86emuOp2_illegal_op,
1605 /* 0x30 */ x86emuOp2_illegal_op,
1606 /* 0x31 */ x86emuOp2_illegal_op,
1607 /* 0x32 */ x86emuOp2_illegal_op,
1608 /* 0x33 */ x86emuOp2_illegal_op,
1609 /* 0x34 */ x86emuOp2_illegal_op,
1610 /* 0x35 */ x86emuOp2_illegal_op,
1611 /* 0x36 */ x86emuOp2_illegal_op,
1612 /* 0x37 */ x86emuOp2_illegal_op,
1613 /* 0x38 */ x86emuOp2_illegal_op,
1614 /* 0x39 */ x86emuOp2_illegal_op,
1615 /* 0x3a */ x86emuOp2_illegal_op,
1616 /* 0x3b */ x86emuOp2_illegal_op,
1617 /* 0x3c */ x86emuOp2_illegal_op,
1618 /* 0x3d */ x86emuOp2_illegal_op,
1619 /* 0x3e */ x86emuOp2_illegal_op,
1620 /* 0x3f */ x86emuOp2_illegal_op,
1622 /* 0x40 */ x86emuOp2_illegal_op,
1623 /* 0x41 */ x86emuOp2_illegal_op,
1624 /* 0x42 */ x86emuOp2_illegal_op,
1625 /* 0x43 */ x86emuOp2_illegal_op,
1626 /* 0x44 */ x86emuOp2_illegal_op,
1627 /* 0x45 */ x86emuOp2_illegal_op,
1628 /* 0x46 */ x86emuOp2_illegal_op,
1629 /* 0x47 */ x86emuOp2_illegal_op,
1630 /* 0x48 */ x86emuOp2_illegal_op,
1631 /* 0x49 */ x86emuOp2_illegal_op,
1632 /* 0x4a */ x86emuOp2_illegal_op,
1633 /* 0x4b */ x86emuOp2_illegal_op,
1634 /* 0x4c */ x86emuOp2_illegal_op,
1635 /* 0x4d */ x86emuOp2_illegal_op,
1636 /* 0x4e */ x86emuOp2_illegal_op,
1637 /* 0x4f */ x86emuOp2_illegal_op,
1639 /* 0x50 */ x86emuOp2_illegal_op,
1640 /* 0x51 */ x86emuOp2_illegal_op,
1641 /* 0x52 */ x86emuOp2_illegal_op,
1642 /* 0x53 */ x86emuOp2_illegal_op,
1643 /* 0x54 */ x86emuOp2_illegal_op,
1644 /* 0x55 */ x86emuOp2_illegal_op,
1645 /* 0x56 */ x86emuOp2_illegal_op,
1646 /* 0x57 */ x86emuOp2_illegal_op,
1647 /* 0x58 */ x86emuOp2_illegal_op,
1648 /* 0x59 */ x86emuOp2_illegal_op,
1649 /* 0x5a */ x86emuOp2_illegal_op,
1650 /* 0x5b */ x86emuOp2_illegal_op,
1651 /* 0x5c */ x86emuOp2_illegal_op,
1652 /* 0x5d */ x86emuOp2_illegal_op,
1653 /* 0x5e */ x86emuOp2_illegal_op,
1654 /* 0x5f */ x86emuOp2_illegal_op,
1656 /* 0x60 */ x86emuOp2_illegal_op,
1657 /* 0x61 */ x86emuOp2_illegal_op,
1658 /* 0x62 */ x86emuOp2_illegal_op,
1659 /* 0x63 */ x86emuOp2_illegal_op,
1660 /* 0x64 */ x86emuOp2_illegal_op,
1661 /* 0x65 */ x86emuOp2_illegal_op,
1662 /* 0x66 */ x86emuOp2_illegal_op,
1663 /* 0x67 */ x86emuOp2_illegal_op,
1664 /* 0x68 */ x86emuOp2_illegal_op,
1665 /* 0x69 */ x86emuOp2_illegal_op,
1666 /* 0x6a */ x86emuOp2_illegal_op,
1667 /* 0x6b */ x86emuOp2_illegal_op,
1668 /* 0x6c */ x86emuOp2_illegal_op,
1669 /* 0x6d */ x86emuOp2_illegal_op,
1670 /* 0x6e */ x86emuOp2_illegal_op,
1671 /* 0x6f */ x86emuOp2_illegal_op,
1673 /* 0x70 */ x86emuOp2_illegal_op,
1674 /* 0x71 */ x86emuOp2_illegal_op,
1675 /* 0x72 */ x86emuOp2_illegal_op,
1676 /* 0x73 */ x86emuOp2_illegal_op,
1677 /* 0x74 */ x86emuOp2_illegal_op,
1678 /* 0x75 */ x86emuOp2_illegal_op,
1679 /* 0x76 */ x86emuOp2_illegal_op,
1680 /* 0x77 */ x86emuOp2_illegal_op,
1681 /* 0x78 */ x86emuOp2_illegal_op,
1682 /* 0x79 */ x86emuOp2_illegal_op,
1683 /* 0x7a */ x86emuOp2_illegal_op,
1684 /* 0x7b */ x86emuOp2_illegal_op,
1685 /* 0x7c */ x86emuOp2_illegal_op,
1686 /* 0x7d */ x86emuOp2_illegal_op,
1687 /* 0x7e */ x86emuOp2_illegal_op,
1688 /* 0x7f */ x86emuOp2_illegal_op,
1690 /* 0x80 */ x86emuOp2_long_jump,
1691 /* 0x81 */ x86emuOp2_long_jump,
1692 /* 0x82 */ x86emuOp2_long_jump,
1693 /* 0x83 */ x86emuOp2_long_jump,
1694 /* 0x84 */ x86emuOp2_long_jump,
1695 /* 0x85 */ x86emuOp2_long_jump,
1696 /* 0x86 */ x86emuOp2_long_jump,
1697 /* 0x87 */ x86emuOp2_long_jump,
1698 /* 0x88 */ x86emuOp2_long_jump,
1699 /* 0x89 */ x86emuOp2_long_jump,
1700 /* 0x8a */ x86emuOp2_long_jump,
1701 /* 0x8b */ x86emuOp2_long_jump,
1702 /* 0x8c */ x86emuOp2_long_jump,
1703 /* 0x8d */ x86emuOp2_long_jump,
1704 /* 0x8e */ x86emuOp2_long_jump,
1705 /* 0x8f */ x86emuOp2_long_jump,
1707 /* 0x90 */ x86emuOp2_set_byte,
1708 /* 0x91 */ x86emuOp2_set_byte,
1709 /* 0x92 */ x86emuOp2_set_byte,
1710 /* 0x93 */ x86emuOp2_set_byte,
1711 /* 0x94 */ x86emuOp2_set_byte,
1712 /* 0x95 */ x86emuOp2_set_byte,
1713 /* 0x96 */ x86emuOp2_set_byte,
1714 /* 0x97 */ x86emuOp2_set_byte,
1715 /* 0x98 */ x86emuOp2_set_byte,
1716 /* 0x99 */ x86emuOp2_set_byte,
1717 /* 0x9a */ x86emuOp2_set_byte,
1718 /* 0x9b */ x86emuOp2_set_byte,
1719 /* 0x9c */ x86emuOp2_set_byte,
1720 /* 0x9d */ x86emuOp2_set_byte,
1721 /* 0x9e */ x86emuOp2_set_byte,
1722 /* 0x9f */ x86emuOp2_set_byte,
1724 /* 0xa0 */ x86emuOp2_push_FS,
1725 /* 0xa1 */ x86emuOp2_pop_FS,
1726 /* 0xa2 */ x86emuOp2_illegal_op,
1727 /* 0xa3 */ x86emuOp2_bt_R,
1728 /* 0xa4 */ x86emuOp2_shld_IMM,
1729 /* 0xa5 */ x86emuOp2_shld_CL,
1730 /* 0xa6 */ x86emuOp2_illegal_op,
1731 /* 0xa7 */ x86emuOp2_illegal_op,
1732 /* 0xa8 */ x86emuOp2_push_GS,
1733 /* 0xa9 */ x86emuOp2_pop_GS,
1734 /* 0xaa */ x86emuOp2_illegal_op,
1735 /* 0xab */ x86emuOp2_bt_R,
1736 /* 0xac */ x86emuOp2_shrd_IMM,
1737 /* 0xad */ x86emuOp2_shrd_CL,
1738 /* 0xae */ x86emuOp2_illegal_op,
1739 /* 0xaf */ x86emuOp2_imul_R_RM,
1741 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1742 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1743 /* 0xb2 */ x86emuOp2_lss_R_IMM,
1744 /* 0xb3 */ x86emuOp2_btr_R,
1745 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
1746 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
1747 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
1748 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
1749 /* 0xb8 */ x86emuOp2_illegal_op,
1750 /* 0xb9 */ x86emuOp2_illegal_op,
1751 /* 0xba */ x86emuOp2_btX_I,
1752 /* 0xbb */ x86emuOp2_btc_R,
1753 /* 0xbc */ x86emuOp2_bsf,
1754 /* 0xbd */ x86emuOp2_bsr,
1755 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
1756 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
1758 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
1759 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
1760 /* 0xc2 */ x86emuOp2_illegal_op,
1761 /* 0xc3 */ x86emuOp2_illegal_op,
1762 /* 0xc4 */ x86emuOp2_illegal_op,
1763 /* 0xc5 */ x86emuOp2_illegal_op,
1764 /* 0xc6 */ x86emuOp2_illegal_op,
1765 /* 0xc7 */ x86emuOp2_illegal_op,
1766 /* 0xc8 */ x86emuOp2_bswap,
1767 /* 0xc9 */ x86emuOp2_bswap,
1768 /* 0xca */ x86emuOp2_bswap,
1769 /* 0xcb */ x86emuOp2_bswap,
1770 /* 0xcc */ x86emuOp2_bswap,
1771 /* 0xcd */ x86emuOp2_bswap,
1772 /* 0xce */ x86emuOp2_bswap,
1773 /* 0xcf */ x86emuOp2_bswap,
1775 /* 0xd0 */ x86emuOp2_illegal_op,
1776 /* 0xd1 */ x86emuOp2_illegal_op,
1777 /* 0xd2 */ x86emuOp2_illegal_op,
1778 /* 0xd3 */ x86emuOp2_illegal_op,
1779 /* 0xd4 */ x86emuOp2_illegal_op,
1780 /* 0xd5 */ x86emuOp2_illegal_op,
1781 /* 0xd6 */ x86emuOp2_illegal_op,
1782 /* 0xd7 */ x86emuOp2_illegal_op,
1783 /* 0xd8 */ x86emuOp2_illegal_op,
1784 /* 0xd9 */ x86emuOp2_illegal_op,
1785 /* 0xda */ x86emuOp2_illegal_op,
1786 /* 0xdb */ x86emuOp2_illegal_op,
1787 /* 0xdc */ x86emuOp2_illegal_op,
1788 /* 0xdd */ x86emuOp2_illegal_op,
1789 /* 0xde */ x86emuOp2_illegal_op,
1790 /* 0xdf */ x86emuOp2_illegal_op,
1792 /* 0xe0 */ x86emuOp2_illegal_op,
1793 /* 0xe1 */ x86emuOp2_illegal_op,
1794 /* 0xe2 */ x86emuOp2_illegal_op,
1795 /* 0xe3 */ x86emuOp2_illegal_op,
1796 /* 0xe4 */ x86emuOp2_illegal_op,
1797 /* 0xe5 */ x86emuOp2_illegal_op,
1798 /* 0xe6 */ x86emuOp2_illegal_op,
1799 /* 0xe7 */ x86emuOp2_illegal_op,
1800 /* 0xe8 */ x86emuOp2_illegal_op,
1801 /* 0xe9 */ x86emuOp2_illegal_op,
1802 /* 0xea */ x86emuOp2_illegal_op,
1803 /* 0xeb */ x86emuOp2_illegal_op,
1804 /* 0xec */ x86emuOp2_illegal_op,
1805 /* 0xed */ x86emuOp2_illegal_op,
1806 /* 0xee */ x86emuOp2_illegal_op,
1807 /* 0xef */ x86emuOp2_illegal_op,
1809 /* 0xf0 */ x86emuOp2_illegal_op,
1810 /* 0xf1 */ x86emuOp2_illegal_op,
1811 /* 0xf2 */ x86emuOp2_illegal_op,
1812 /* 0xf3 */ x86emuOp2_illegal_op,
1813 /* 0xf4 */ x86emuOp2_illegal_op,
1814 /* 0xf5 */ x86emuOp2_illegal_op,
1815 /* 0xf6 */ x86emuOp2_illegal_op,
1816 /* 0xf7 */ x86emuOp2_illegal_op,
1817 /* 0xf8 */ x86emuOp2_illegal_op,
1818 /* 0xf9 */ x86emuOp2_illegal_op,
1819 /* 0xfa */ x86emuOp2_illegal_op,
1820 /* 0xfb */ x86emuOp2_illegal_op,
1821 /* 0xfc */ x86emuOp2_illegal_op,
1822 /* 0xfd */ x86emuOp2_illegal_op,
1823 /* 0xfe */ x86emuOp2_illegal_op,
1824 /* 0xff */ x86emuOp2_illegal_op,