1 /****************************************************************************
3 * Realmode X86 Emulator Library
5 * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
6 * Jason Jin <Jason.jin@freescale.com>
8 * Copyright (C) 1991-2004 SciTech Software, Inc.
9 * Copyright (C) David Mosberger-Tang
10 * Copyright (C) 1999 Egbert Eich
12 * ========================================================================
14 * Permission to use, copy, modify, distribute, and sell this software and
15 * its documentation for any purpose is hereby granted without fee,
16 * provided that the above copyright notice appear in all copies and that
17 * both that copyright notice and this permission notice appear in
18 * supporting documentation, and that the name of the authors not be used
19 * in advertising or publicity pertaining to distribution of the software
20 * without specific, written prior permission. The authors makes no
21 * representations about the suitability of this software for any purpose.
22 * It is provided "as is" without express or implied warranty.
24 * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
25 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
26 * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
27 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
28 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
29 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
30 * PERFORMANCE OF THIS SOFTWARE.
32 * ========================================================================
36 * Developer: Kendall Bennett
38 * Description: This file includes subroutines to implement the decoding
39 * and emulation of all the x86 extended two-byte processor
42 * Jason port this file to u-boot. Put the function pointer into
45 ****************************************************************************/
47 #include "x86emu/x86emui.h"
49 #if defined(CONFIG_BIOSEMU)
51 /*----------------------------- Implementation ----------------------------*/
53 /****************************************************************************
55 op1 - Instruction op code
58 Handles illegal opcodes.
59 ****************************************************************************/
60 void x86emuOp2_illegal_op(
64 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
66 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
67 M.x86.R_CS, M.x86.R_IP-2,op2);
72 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
74 /****************************************************************************
76 Handles opcode 0x0f,0x80-0x8F
77 ****************************************************************************/
78 int x86emu_check_jump_condition(u8 op)
82 DECODE_PRINTF("JO\t");
83 return ACCESS_FLAG(F_OF);
85 DECODE_PRINTF("JNO\t");
86 return !ACCESS_FLAG(F_OF);
89 DECODE_PRINTF("JB\t");
90 return ACCESS_FLAG(F_CF);
93 DECODE_PRINTF("JNB\t");
94 return !ACCESS_FLAG(F_CF);
97 DECODE_PRINTF("JZ\t");
98 return ACCESS_FLAG(F_ZF);
101 DECODE_PRINTF("JNZ\t");
102 return !ACCESS_FLAG(F_ZF);
105 DECODE_PRINTF("JBE\t");
106 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
109 DECODE_PRINTF("JNBE\t");
110 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
113 DECODE_PRINTF("JS\t");
114 return ACCESS_FLAG(F_SF);
117 DECODE_PRINTF("JNS\t");
118 return !ACCESS_FLAG(F_SF);
121 DECODE_PRINTF("JP\t");
122 return ACCESS_FLAG(F_PF);
125 DECODE_PRINTF("JNP\t");
126 return !ACCESS_FLAG(F_PF);
129 DECODE_PRINTF("JL\t");
130 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
133 DECODE_PRINTF("JNL\t");
134 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
137 DECODE_PRINTF("JLE\t");
138 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
142 DECODE_PRINTF("JNLE\t");
143 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
148 void x86emuOp2_long_jump(u8 op2)
153 /* conditional jump to word offset. */
155 cond = x86emu_check_jump_condition(op2 & 0xF);
156 target = (s16) fetch_word_imm();
157 target += (s16) M.x86.R_IP;
158 DECODE_PRINTF2("%04x\n", target);
161 M.x86.R_IP = (u16)target;
162 DECODE_CLEAR_SEGOVR();
166 /****************************************************************************
168 Handles opcode 0x0f,0x90-0x9F
169 ****************************************************************************/
170 void x86emuOp2_set_byte(u8 op2)
182 cond = ACCESS_FLAG(F_OF);
186 cond = !ACCESS_FLAG(F_OF);
190 cond = ACCESS_FLAG(F_CF);
194 cond = !ACCESS_FLAG(F_CF);
198 cond = ACCESS_FLAG(F_ZF);
202 cond = !ACCESS_FLAG(F_ZF);
206 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
210 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
214 cond = ACCESS_FLAG(F_SF);
218 cond = !ACCESS_FLAG(F_SF);
222 cond = ACCESS_FLAG(F_PF);
226 cond = !ACCESS_FLAG(F_PF);
230 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
234 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
238 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
243 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
248 FETCH_DECODE_MODRM(mod, rh, rl);
250 destoffset = decode_rmXX_address(mod, rl);
252 store_data_byte(destoffset, cond ? 0x01 : 0x00);
253 } else { /* register to register */
254 destreg = DECODE_RM_BYTE_REGISTER(rl);
256 *destreg = cond ? 0x01 : 0x00;
258 DECODE_CLEAR_SEGOVR();
262 /****************************************************************************
264 Handles opcode 0x0f,0xa0
265 ****************************************************************************/
266 void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
269 DECODE_PRINTF("PUSH\tFS\n");
271 push_word(M.x86.R_FS);
272 DECODE_CLEAR_SEGOVR();
276 /****************************************************************************
278 Handles opcode 0x0f,0xa1
279 ****************************************************************************/
280 void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
283 DECODE_PRINTF("POP\tFS\n");
285 M.x86.R_FS = pop_word();
286 DECODE_CLEAR_SEGOVR();
290 /****************************************************************************
292 Handles opcode 0x0f,0xa3
293 ****************************************************************************/
294 void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
301 DECODE_PRINTF("BT\t");
302 FETCH_DECODE_MODRM(mod, rh, rl);
304 srcoffset = decode_rmXX_address(mod, rl);
305 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
310 shiftreg = DECODE_RM_LONG_REGISTER(rh);
312 bit = *shiftreg & 0x1F;
313 disp = (s16)*shiftreg >> 5;
314 srcval = fetch_data_long(srcoffset+disp);
315 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
321 shiftreg = DECODE_RM_WORD_REGISTER(rh);
323 bit = *shiftreg & 0xF;
324 disp = (s16)*shiftreg >> 4;
325 srcval = fetch_data_word(srcoffset+disp);
326 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
328 } else { /* register to register */
329 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
330 u32 *srcreg,*shiftreg;
332 srcreg = DECODE_RM_LONG_REGISTER(rl);
334 shiftreg = DECODE_RM_LONG_REGISTER(rh);
336 bit = *shiftreg & 0x1F;
337 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
339 u16 *srcreg,*shiftreg;
341 srcreg = DECODE_RM_WORD_REGISTER(rl);
343 shiftreg = DECODE_RM_WORD_REGISTER(rh);
345 bit = *shiftreg & 0xF;
346 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
349 DECODE_CLEAR_SEGOVR();
353 /****************************************************************************
355 Handles opcode 0x0f,0xa4
356 ****************************************************************************/
357 void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
364 DECODE_PRINTF("SHLD\t");
365 FETCH_DECODE_MODRM(mod, rh, rl);
367 destoffset = decode_rmXX_address(mod, rl);
368 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
373 shiftreg = DECODE_RM_LONG_REGISTER(rh);
375 shift = fetch_byte_imm();
376 DECODE_PRINTF2("%d\n", shift);
378 destval = fetch_data_long(destoffset);
379 destval = shld_long(destval,*shiftreg,shift);
380 store_data_long(destoffset, destval);
386 shiftreg = DECODE_RM_WORD_REGISTER(rh);
388 shift = fetch_byte_imm();
389 DECODE_PRINTF2("%d\n", shift);
391 destval = fetch_data_word(destoffset);
392 destval = shld_word(destval,*shiftreg,shift);
393 store_data_word(destoffset, destval);
395 } else { /* register to register */
396 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
397 u32 *destreg,*shiftreg;
399 destreg = DECODE_RM_LONG_REGISTER(rl);
401 shiftreg = DECODE_RM_LONG_REGISTER(rh);
403 shift = fetch_byte_imm();
404 DECODE_PRINTF2("%d\n", shift);
406 *destreg = shld_long(*destreg,*shiftreg,shift);
408 u16 *destreg,*shiftreg;
410 destreg = DECODE_RM_WORD_REGISTER(rl);
412 shiftreg = DECODE_RM_WORD_REGISTER(rh);
414 shift = fetch_byte_imm();
415 DECODE_PRINTF2("%d\n", shift);
417 *destreg = shld_word(*destreg,*shiftreg,shift);
420 DECODE_CLEAR_SEGOVR();
424 /****************************************************************************
426 Handles opcode 0x0f,0xa5
427 ****************************************************************************/
428 void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
434 DECODE_PRINTF("SHLD\t");
435 FETCH_DECODE_MODRM(mod, rh, rl);
437 destoffset = decode_rmXX_address(mod, rl);
438 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
443 shiftreg = DECODE_RM_LONG_REGISTER(rh);
444 DECODE_PRINTF(",CL\n");
446 destval = fetch_data_long(destoffset);
447 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
448 store_data_long(destoffset, destval);
454 shiftreg = DECODE_RM_WORD_REGISTER(rh);
455 DECODE_PRINTF(",CL\n");
457 destval = fetch_data_word(destoffset);
458 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
459 store_data_word(destoffset, destval);
461 } else { /* register to register */
462 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
463 u32 *destreg,*shiftreg;
465 destreg = DECODE_RM_LONG_REGISTER(rl);
467 shiftreg = DECODE_RM_LONG_REGISTER(rh);
468 DECODE_PRINTF(",CL\n");
470 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
472 u16 *destreg,*shiftreg;
474 destreg = DECODE_RM_WORD_REGISTER(rl);
476 shiftreg = DECODE_RM_WORD_REGISTER(rh);
477 DECODE_PRINTF(",CL\n");
479 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
482 DECODE_CLEAR_SEGOVR();
486 /****************************************************************************
488 Handles opcode 0x0f,0xa8
489 ****************************************************************************/
490 void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
493 DECODE_PRINTF("PUSH\tGS\n");
495 push_word(M.x86.R_GS);
496 DECODE_CLEAR_SEGOVR();
500 /****************************************************************************
502 Handles opcode 0x0f,0xa9
503 ****************************************************************************/
504 void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
507 DECODE_PRINTF("POP\tGS\n");
509 M.x86.R_GS = pop_word();
510 DECODE_CLEAR_SEGOVR();
514 /****************************************************************************
516 Handles opcode 0x0f,0xaa
517 ****************************************************************************/
518 void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
525 DECODE_PRINTF("BTS\t");
526 FETCH_DECODE_MODRM(mod, rh, rl);
528 srcoffset = decode_rmXX_address(mod, rl);
529 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
534 shiftreg = DECODE_RM_LONG_REGISTER(rh);
536 bit = *shiftreg & 0x1F;
537 disp = (s16)*shiftreg >> 5;
538 srcval = fetch_data_long(srcoffset+disp);
540 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
541 store_data_long(srcoffset+disp, srcval | mask);
547 shiftreg = DECODE_RM_WORD_REGISTER(rh);
549 bit = *shiftreg & 0xF;
550 disp = (s16)*shiftreg >> 4;
551 srcval = fetch_data_word(srcoffset+disp);
552 mask = (u16)(0x1 << bit);
553 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
554 store_data_word(srcoffset+disp, srcval | mask);
556 } else { /* register to register */
557 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
558 u32 *srcreg,*shiftreg;
561 srcreg = DECODE_RM_LONG_REGISTER(rl);
563 shiftreg = DECODE_RM_LONG_REGISTER(rh);
565 bit = *shiftreg & 0x1F;
567 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
570 u16 *srcreg,*shiftreg;
573 srcreg = DECODE_RM_WORD_REGISTER(rl);
575 shiftreg = DECODE_RM_WORD_REGISTER(rh);
577 bit = *shiftreg & 0xF;
578 mask = (u16)(0x1 << bit);
579 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
583 DECODE_CLEAR_SEGOVR();
587 /****************************************************************************
589 Handles opcode 0x0f,0xac
590 ****************************************************************************/
591 void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
598 DECODE_PRINTF("SHLD\t");
599 FETCH_DECODE_MODRM(mod, rh, rl);
601 destoffset = decode_rmXX_address(mod, rl);
602 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
607 shiftreg = DECODE_RM_LONG_REGISTER(rh);
609 shift = fetch_byte_imm();
610 DECODE_PRINTF2("%d\n", shift);
612 destval = fetch_data_long(destoffset);
613 destval = shrd_long(destval,*shiftreg,shift);
614 store_data_long(destoffset, destval);
620 shiftreg = DECODE_RM_WORD_REGISTER(rh);
622 shift = fetch_byte_imm();
623 DECODE_PRINTF2("%d\n", shift);
625 destval = fetch_data_word(destoffset);
626 destval = shrd_word(destval,*shiftreg,shift);
627 store_data_word(destoffset, destval);
629 } else { /* register to register */
630 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
631 u32 *destreg,*shiftreg;
633 destreg = DECODE_RM_LONG_REGISTER(rl);
635 shiftreg = DECODE_RM_LONG_REGISTER(rh);
637 shift = fetch_byte_imm();
638 DECODE_PRINTF2("%d\n", shift);
640 *destreg = shrd_long(*destreg,*shiftreg,shift);
642 u16 *destreg,*shiftreg;
644 destreg = DECODE_RM_WORD_REGISTER(rl);
646 shiftreg = DECODE_RM_WORD_REGISTER(rh);
648 shift = fetch_byte_imm();
649 DECODE_PRINTF2("%d\n", shift);
651 *destreg = shrd_word(*destreg,*shiftreg,shift);
654 DECODE_CLEAR_SEGOVR();
658 /****************************************************************************
660 Handles opcode 0x0f,0xad
661 ****************************************************************************/
662 void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
668 DECODE_PRINTF("SHLD\t");
669 FETCH_DECODE_MODRM(mod, rh, rl);
671 destoffset = decode_rmXX_address(mod, rl);
673 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
677 shiftreg = DECODE_RM_LONG_REGISTER(rh);
678 DECODE_PRINTF(",CL\n");
680 destval = fetch_data_long(destoffset);
681 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
682 store_data_long(destoffset, destval);
687 shiftreg = DECODE_RM_WORD_REGISTER(rh);
688 DECODE_PRINTF(",CL\n");
690 destval = fetch_data_word(destoffset);
691 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
692 store_data_word(destoffset, destval);
694 } else { /* register to register */
695 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
696 u32 *destreg,*shiftreg;
698 destreg = DECODE_RM_LONG_REGISTER(rl);
700 shiftreg = DECODE_RM_LONG_REGISTER(rh);
701 DECODE_PRINTF(",CL\n");
703 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
705 u16 *destreg,*shiftreg;
707 destreg = DECODE_RM_WORD_REGISTER(rl);
709 shiftreg = DECODE_RM_WORD_REGISTER(rh);
710 DECODE_PRINTF(",CL\n");
712 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
715 DECODE_CLEAR_SEGOVR();
719 /****************************************************************************
721 Handles opcode 0x0f,0xaf
722 ****************************************************************************/
723 void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
729 DECODE_PRINTF("IMUL\t");
730 FETCH_DECODE_MODRM(mod, rh, rl);
732 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
737 destreg = DECODE_RM_LONG_REGISTER(rh);
739 srcoffset = decode_rmXX_address(mod, rl);
740 srcval = fetch_data_long(srcoffset);
742 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
750 *destreg = (u32)res_lo;
756 destreg = DECODE_RM_WORD_REGISTER(rh);
758 srcoffset = decode_rmXX_address(mod, rl);
759 srcval = fetch_data_word(srcoffset);
761 res = (s16)*destreg * (s16)srcval;
771 } else { /* register to register */
772 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
773 u32 *destreg,*srcreg;
776 destreg = DECODE_RM_LONG_REGISTER(rh);
778 srcreg = DECODE_RM_LONG_REGISTER(rl);
780 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
788 *destreg = (u32)res_lo;
790 u16 *destreg,*srcreg;
793 destreg = DECODE_RM_WORD_REGISTER(rh);
795 srcreg = DECODE_RM_WORD_REGISTER(rl);
796 res = (s16)*destreg * (s16)*srcreg;
807 DECODE_CLEAR_SEGOVR();
811 /****************************************************************************
813 Handles opcode 0x0f,0xb2
814 ****************************************************************************/
815 void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
822 DECODE_PRINTF("LSS\t");
823 FETCH_DECODE_MODRM(mod, rh, rl);
825 dstreg = DECODE_RM_WORD_REGISTER(rh);
827 srcoffset = decode_rmXX_address(mod, rl);
830 *dstreg = fetch_data_word(srcoffset);
831 M.x86.R_SS = fetch_data_word(srcoffset + 2);
832 } else { /* register to register */
836 DECODE_CLEAR_SEGOVR();
840 /****************************************************************************
842 Handles opcode 0x0f,0xb3
843 ****************************************************************************/
844 void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
851 DECODE_PRINTF("BTR\t");
852 FETCH_DECODE_MODRM(mod, rh, rl);
854 srcoffset = decode_rmXX_address(mod, rl);
856 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
860 shiftreg = DECODE_RM_LONG_REGISTER(rh);
862 bit = *shiftreg & 0x1F;
863 disp = (s16)*shiftreg >> 5;
864 srcval = fetch_data_long(srcoffset+disp);
866 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
867 store_data_long(srcoffset+disp, srcval & ~mask);
872 shiftreg = DECODE_RM_WORD_REGISTER(rh);
874 bit = *shiftreg & 0xF;
875 disp = (s16)*shiftreg >> 4;
876 srcval = fetch_data_word(srcoffset+disp);
877 mask = (u16)(0x1 << bit);
878 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
879 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
881 } else { /* register to register */
882 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
883 u32 *srcreg,*shiftreg;
886 srcreg = DECODE_RM_LONG_REGISTER(rl);
888 shiftreg = DECODE_RM_LONG_REGISTER(rh);
890 bit = *shiftreg & 0x1F;
892 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
895 u16 *srcreg,*shiftreg;
898 srcreg = DECODE_RM_WORD_REGISTER(rl);
900 shiftreg = DECODE_RM_WORD_REGISTER(rh);
902 bit = *shiftreg & 0xF;
903 mask = (u16)(0x1 << bit);
904 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
908 DECODE_CLEAR_SEGOVR();
912 /****************************************************************************
914 Handles opcode 0x0f,0xb4
915 ****************************************************************************/
916 void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
923 DECODE_PRINTF("LFS\t");
924 FETCH_DECODE_MODRM(mod, rh, rl);
926 dstreg = DECODE_RM_WORD_REGISTER(rh);
928 srcoffset = decode_rmXX_address(mod, rl);
931 *dstreg = fetch_data_word(srcoffset);
932 M.x86.R_FS = fetch_data_word(srcoffset + 2);
933 } else { /* register to register */
937 DECODE_CLEAR_SEGOVR();
941 /****************************************************************************
943 Handles opcode 0x0f,0xb5
944 ****************************************************************************/
945 void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
952 DECODE_PRINTF("LGS\t");
953 FETCH_DECODE_MODRM(mod, rh, rl);
955 dstreg = DECODE_RM_WORD_REGISTER(rh);
957 srcoffset = decode_rmXX_address(mod, rl);
960 *dstreg = fetch_data_word(srcoffset);
961 M.x86.R_GS = fetch_data_word(srcoffset + 2);
962 } else { /* register to register */
966 DECODE_CLEAR_SEGOVR();
970 /****************************************************************************
972 Handles opcode 0x0f,0xb6
973 ****************************************************************************/
974 void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
980 DECODE_PRINTF("MOVZX\t");
981 FETCH_DECODE_MODRM(mod, rh, rl);
983 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
987 destreg = DECODE_RM_LONG_REGISTER(rh);
989 srcoffset = decode_rmXX_address(mod, rl);
990 srcval = fetch_data_byte(srcoffset);
998 destreg = DECODE_RM_WORD_REGISTER(rh);
1000 srcoffset = decode_rmXX_address(mod, rl);
1001 srcval = fetch_data_byte(srcoffset);
1002 DECODE_PRINTF("\n");
1006 } else { /* register to register */
1007 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1011 destreg = DECODE_RM_LONG_REGISTER(rh);
1013 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1014 DECODE_PRINTF("\n");
1021 destreg = DECODE_RM_WORD_REGISTER(rh);
1023 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1024 DECODE_PRINTF("\n");
1029 DECODE_CLEAR_SEGOVR();
1033 /****************************************************************************
1035 Handles opcode 0x0f,0xb7
1036 ****************************************************************************/
1037 void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1046 DECODE_PRINTF("MOVZX\t");
1047 FETCH_DECODE_MODRM(mod, rh, rl);
1049 destreg = DECODE_RM_LONG_REGISTER(rh);
1051 srcoffset = decode_rmXX_address(mod, rl);
1052 srcval = fetch_data_word(srcoffset);
1053 DECODE_PRINTF("\n");
1056 } else { /* register to register */
1057 destreg = DECODE_RM_LONG_REGISTER(rh);
1059 srcreg = DECODE_RM_WORD_REGISTER(rl);
1060 DECODE_PRINTF("\n");
1064 DECODE_CLEAR_SEGOVR();
1068 /****************************************************************************
1070 Handles opcode 0x0f,0xba
1071 ****************************************************************************/
1072 void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1080 FETCH_DECODE_MODRM(mod, rh, rl);
1083 DECODE_PRINTF("BT\t");
1086 DECODE_PRINTF("BTS\t");
1089 DECODE_PRINTF("BTR\t");
1092 DECODE_PRINTF("BTC\t");
1095 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1097 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1098 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1103 srcoffset = decode_rmXX_address(mod, rl);
1104 shift = fetch_byte_imm();
1105 DECODE_PRINTF2(",%d\n", shift);
1108 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1112 srcval = fetch_data_long(srcoffset);
1113 mask = (0x1 << bit);
1114 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1117 store_data_long(srcoffset, srcval | mask);
1120 store_data_long(srcoffset, srcval & ~mask);
1123 store_data_long(srcoffset, srcval ^ mask);
1132 srcval = fetch_data_word(srcoffset);
1133 mask = (0x1 << bit);
1134 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1137 store_data_word(srcoffset, srcval | mask);
1140 store_data_word(srcoffset, srcval & ~mask);
1143 store_data_word(srcoffset, srcval ^ mask);
1149 } else { /* register to register */
1150 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1154 srcreg = DECODE_RM_LONG_REGISTER(rl);
1155 shift = fetch_byte_imm();
1156 DECODE_PRINTF2(",%d\n", shift);
1159 mask = (0x1 << bit);
1160 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1178 srcreg = DECODE_RM_WORD_REGISTER(rl);
1179 shift = fetch_byte_imm();
1180 DECODE_PRINTF2(",%d\n", shift);
1183 mask = (0x1 << bit);
1184 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1200 DECODE_CLEAR_SEGOVR();
1204 /****************************************************************************
1206 Handles opcode 0x0f,0xbb
1207 ****************************************************************************/
1208 void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1215 DECODE_PRINTF("BTC\t");
1216 FETCH_DECODE_MODRM(mod, rh, rl);
1218 srcoffset = decode_rmXX_address(mod, rl);
1220 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1224 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1226 bit = *shiftreg & 0x1F;
1227 disp = (s16)*shiftreg >> 5;
1228 srcval = fetch_data_long(srcoffset+disp);
1229 mask = (0x1 << bit);
1230 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1231 store_data_long(srcoffset+disp, srcval ^ mask);
1236 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1238 bit = *shiftreg & 0xF;
1239 disp = (s16)*shiftreg >> 4;
1240 srcval = fetch_data_word(srcoffset+disp);
1241 mask = (u16)(0x1 << bit);
1242 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1243 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1245 } else { /* register to register */
1246 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1247 u32 *srcreg,*shiftreg;
1250 srcreg = DECODE_RM_LONG_REGISTER(rl);
1252 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1254 bit = *shiftreg & 0x1F;
1255 mask = (0x1 << bit);
1256 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1259 u16 *srcreg,*shiftreg;
1262 srcreg = DECODE_RM_WORD_REGISTER(rl);
1264 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1266 bit = *shiftreg & 0xF;
1267 mask = (u16)(0x1 << bit);
1268 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1272 DECODE_CLEAR_SEGOVR();
1276 /****************************************************************************
1278 Handles opcode 0x0f,0xbc
1279 ****************************************************************************/
1280 void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1286 DECODE_PRINTF("BSF\n");
1287 FETCH_DECODE_MODRM(mod, rh, rl);
1289 srcoffset = decode_rmXX_address(mod, rl);
1291 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1292 u32 srcval, *dstreg;
1294 dstreg = DECODE_RM_LONG_REGISTER(rh);
1296 srcval = fetch_data_long(srcoffset);
1297 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1298 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1299 if ((srcval >> *dstreg) & 1) break;
1301 u16 srcval, *dstreg;
1303 dstreg = DECODE_RM_WORD_REGISTER(rh);
1305 srcval = fetch_data_word(srcoffset);
1306 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1307 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1308 if ((srcval >> *dstreg) & 1) break;
1310 } else { /* register to register */
1311 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1312 u32 *srcreg, *dstreg;
1314 srcreg = DECODE_RM_LONG_REGISTER(rl);
1316 dstreg = DECODE_RM_LONG_REGISTER(rh);
1318 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1319 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1320 if ((*srcreg >> *dstreg) & 1) break;
1322 u16 *srcreg, *dstreg;
1324 srcreg = DECODE_RM_WORD_REGISTER(rl);
1326 dstreg = DECODE_RM_WORD_REGISTER(rh);
1328 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1329 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1330 if ((*srcreg >> *dstreg) & 1) break;
1333 DECODE_CLEAR_SEGOVR();
1337 /****************************************************************************
1339 Handles opcode 0x0f,0xbd
1340 ****************************************************************************/
1341 void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1347 DECODE_PRINTF("BSF\n");
1348 FETCH_DECODE_MODRM(mod, rh, rl);
1350 srcoffset = decode_rmXX_address(mod, rl);
1352 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1353 u32 srcval, *dstreg;
1355 dstreg = DECODE_RM_LONG_REGISTER(rh);
1357 srcval = fetch_data_long(srcoffset);
1358 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1359 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1360 if ((srcval >> *dstreg) & 1) break;
1362 u16 srcval, *dstreg;
1364 dstreg = DECODE_RM_WORD_REGISTER(rh);
1366 srcval = fetch_data_word(srcoffset);
1367 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1368 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1369 if ((srcval >> *dstreg) & 1) break;
1371 } else { /* register to register */
1372 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1373 u32 *srcreg, *dstreg;
1375 srcreg = DECODE_RM_LONG_REGISTER(rl);
1377 dstreg = DECODE_RM_LONG_REGISTER(rh);
1379 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1380 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1381 if ((*srcreg >> *dstreg) & 1) break;
1383 u16 *srcreg, *dstreg;
1385 srcreg = DECODE_RM_WORD_REGISTER(rl);
1387 dstreg = DECODE_RM_WORD_REGISTER(rh);
1389 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1390 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1391 if ((*srcreg >> *dstreg) & 1) break;
1394 DECODE_CLEAR_SEGOVR();
1398 /****************************************************************************
1400 Handles opcode 0x0f,0xbe
1401 ****************************************************************************/
1402 void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1408 DECODE_PRINTF("MOVSX\t");
1409 FETCH_DECODE_MODRM(mod, rh, rl);
1411 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1415 destreg = DECODE_RM_LONG_REGISTER(rh);
1417 srcoffset = decode_rmXX_address(mod, rl);
1418 srcval = (s32)((s8)fetch_data_byte(srcoffset));
1419 DECODE_PRINTF("\n");
1426 destreg = DECODE_RM_WORD_REGISTER(rh);
1428 srcoffset = decode_rmXX_address(mod, rl);
1429 srcval = (s16)((s8)fetch_data_byte(srcoffset));
1430 DECODE_PRINTF("\n");
1434 } else { /* register to register */
1435 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1439 destreg = DECODE_RM_LONG_REGISTER(rh);
1441 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1442 DECODE_PRINTF("\n");
1444 *destreg = (s32)((s8)*srcreg);
1449 destreg = DECODE_RM_WORD_REGISTER(rh);
1451 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1452 DECODE_PRINTF("\n");
1454 *destreg = (s16)((s8)*srcreg);
1457 DECODE_CLEAR_SEGOVR();
1461 /****************************************************************************
1463 Handles opcode 0x0f,0xbf
1464 ****************************************************************************/
1465 void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1474 DECODE_PRINTF("MOVSX\t");
1475 FETCH_DECODE_MODRM(mod, rh, rl);
1477 destreg = DECODE_RM_LONG_REGISTER(rh);
1479 srcoffset = decode_rmXX_address(mod, rl);
1480 srcval = (s32)((s16)fetch_data_word(srcoffset));
1481 DECODE_PRINTF("\n");
1484 } else { /* register to register */
1485 destreg = DECODE_RM_LONG_REGISTER(rh);
1487 srcreg = DECODE_RM_WORD_REGISTER(rl);
1488 DECODE_PRINTF("\n");
1490 *destreg = (s32)((s16)*srcreg);
1492 DECODE_CLEAR_SEGOVR();
1496 /***************************************************************************
1497 * Double byte operation code table:
1498 **************************************************************************/
1499 void (*x86emu_optab2[256])(u8) __attribute__((section(".got2"))) =
1501 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
1502 /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
1503 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
1504 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
1505 /* 0x04 */ x86emuOp2_illegal_op,
1506 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1507 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
1508 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1509 /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
1510 /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
1511 /* 0x0a */ x86emuOp2_illegal_op,
1512 /* 0x0b */ x86emuOp2_illegal_op,
1513 /* 0x0c */ x86emuOp2_illegal_op,
1514 /* 0x0d */ x86emuOp2_illegal_op,
1515 /* 0x0e */ x86emuOp2_illegal_op,
1516 /* 0x0f */ x86emuOp2_illegal_op,
1518 /* 0x10 */ x86emuOp2_illegal_op,
1519 /* 0x11 */ x86emuOp2_illegal_op,
1520 /* 0x12 */ x86emuOp2_illegal_op,
1521 /* 0x13 */ x86emuOp2_illegal_op,
1522 /* 0x14 */ x86emuOp2_illegal_op,
1523 /* 0x15 */ x86emuOp2_illegal_op,
1524 /* 0x16 */ x86emuOp2_illegal_op,
1525 /* 0x17 */ x86emuOp2_illegal_op,
1526 /* 0x18 */ x86emuOp2_illegal_op,
1527 /* 0x19 */ x86emuOp2_illegal_op,
1528 /* 0x1a */ x86emuOp2_illegal_op,
1529 /* 0x1b */ x86emuOp2_illegal_op,
1530 /* 0x1c */ x86emuOp2_illegal_op,
1531 /* 0x1d */ x86emuOp2_illegal_op,
1532 /* 0x1e */ x86emuOp2_illegal_op,
1533 /* 0x1f */ x86emuOp2_illegal_op,
1535 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
1536 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
1537 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
1538 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
1539 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
1540 /* 0x25 */ x86emuOp2_illegal_op,
1541 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
1542 /* 0x27 */ x86emuOp2_illegal_op,
1543 /* 0x28 */ x86emuOp2_illegal_op,
1544 /* 0x29 */ x86emuOp2_illegal_op,
1545 /* 0x2a */ x86emuOp2_illegal_op,
1546 /* 0x2b */ x86emuOp2_illegal_op,
1547 /* 0x2c */ x86emuOp2_illegal_op,
1548 /* 0x2d */ x86emuOp2_illegal_op,
1549 /* 0x2e */ x86emuOp2_illegal_op,
1550 /* 0x2f */ x86emuOp2_illegal_op,
1552 /* 0x30 */ x86emuOp2_illegal_op,
1553 /* 0x31 */ x86emuOp2_illegal_op,
1554 /* 0x32 */ x86emuOp2_illegal_op,
1555 /* 0x33 */ x86emuOp2_illegal_op,
1556 /* 0x34 */ x86emuOp2_illegal_op,
1557 /* 0x35 */ x86emuOp2_illegal_op,
1558 /* 0x36 */ x86emuOp2_illegal_op,
1559 /* 0x37 */ x86emuOp2_illegal_op,
1560 /* 0x38 */ x86emuOp2_illegal_op,
1561 /* 0x39 */ x86emuOp2_illegal_op,
1562 /* 0x3a */ x86emuOp2_illegal_op,
1563 /* 0x3b */ x86emuOp2_illegal_op,
1564 /* 0x3c */ x86emuOp2_illegal_op,
1565 /* 0x3d */ x86emuOp2_illegal_op,
1566 /* 0x3e */ x86emuOp2_illegal_op,
1567 /* 0x3f */ x86emuOp2_illegal_op,
1569 /* 0x40 */ x86emuOp2_illegal_op,
1570 /* 0x41 */ x86emuOp2_illegal_op,
1571 /* 0x42 */ x86emuOp2_illegal_op,
1572 /* 0x43 */ x86emuOp2_illegal_op,
1573 /* 0x44 */ x86emuOp2_illegal_op,
1574 /* 0x45 */ x86emuOp2_illegal_op,
1575 /* 0x46 */ x86emuOp2_illegal_op,
1576 /* 0x47 */ x86emuOp2_illegal_op,
1577 /* 0x48 */ x86emuOp2_illegal_op,
1578 /* 0x49 */ x86emuOp2_illegal_op,
1579 /* 0x4a */ x86emuOp2_illegal_op,
1580 /* 0x4b */ x86emuOp2_illegal_op,
1581 /* 0x4c */ x86emuOp2_illegal_op,
1582 /* 0x4d */ x86emuOp2_illegal_op,
1583 /* 0x4e */ x86emuOp2_illegal_op,
1584 /* 0x4f */ x86emuOp2_illegal_op,
1586 /* 0x50 */ x86emuOp2_illegal_op,
1587 /* 0x51 */ x86emuOp2_illegal_op,
1588 /* 0x52 */ x86emuOp2_illegal_op,
1589 /* 0x53 */ x86emuOp2_illegal_op,
1590 /* 0x54 */ x86emuOp2_illegal_op,
1591 /* 0x55 */ x86emuOp2_illegal_op,
1592 /* 0x56 */ x86emuOp2_illegal_op,
1593 /* 0x57 */ x86emuOp2_illegal_op,
1594 /* 0x58 */ x86emuOp2_illegal_op,
1595 /* 0x59 */ x86emuOp2_illegal_op,
1596 /* 0x5a */ x86emuOp2_illegal_op,
1597 /* 0x5b */ x86emuOp2_illegal_op,
1598 /* 0x5c */ x86emuOp2_illegal_op,
1599 /* 0x5d */ x86emuOp2_illegal_op,
1600 /* 0x5e */ x86emuOp2_illegal_op,
1601 /* 0x5f */ x86emuOp2_illegal_op,
1603 /* 0x60 */ x86emuOp2_illegal_op,
1604 /* 0x61 */ x86emuOp2_illegal_op,
1605 /* 0x62 */ x86emuOp2_illegal_op,
1606 /* 0x63 */ x86emuOp2_illegal_op,
1607 /* 0x64 */ x86emuOp2_illegal_op,
1608 /* 0x65 */ x86emuOp2_illegal_op,
1609 /* 0x66 */ x86emuOp2_illegal_op,
1610 /* 0x67 */ x86emuOp2_illegal_op,
1611 /* 0x68 */ x86emuOp2_illegal_op,
1612 /* 0x69 */ x86emuOp2_illegal_op,
1613 /* 0x6a */ x86emuOp2_illegal_op,
1614 /* 0x6b */ x86emuOp2_illegal_op,
1615 /* 0x6c */ x86emuOp2_illegal_op,
1616 /* 0x6d */ x86emuOp2_illegal_op,
1617 /* 0x6e */ x86emuOp2_illegal_op,
1618 /* 0x6f */ x86emuOp2_illegal_op,
1620 /* 0x70 */ x86emuOp2_illegal_op,
1621 /* 0x71 */ x86emuOp2_illegal_op,
1622 /* 0x72 */ x86emuOp2_illegal_op,
1623 /* 0x73 */ x86emuOp2_illegal_op,
1624 /* 0x74 */ x86emuOp2_illegal_op,
1625 /* 0x75 */ x86emuOp2_illegal_op,
1626 /* 0x76 */ x86emuOp2_illegal_op,
1627 /* 0x77 */ x86emuOp2_illegal_op,
1628 /* 0x78 */ x86emuOp2_illegal_op,
1629 /* 0x79 */ x86emuOp2_illegal_op,
1630 /* 0x7a */ x86emuOp2_illegal_op,
1631 /* 0x7b */ x86emuOp2_illegal_op,
1632 /* 0x7c */ x86emuOp2_illegal_op,
1633 /* 0x7d */ x86emuOp2_illegal_op,
1634 /* 0x7e */ x86emuOp2_illegal_op,
1635 /* 0x7f */ x86emuOp2_illegal_op,
1637 /* 0x80 */ x86emuOp2_long_jump,
1638 /* 0x81 */ x86emuOp2_long_jump,
1639 /* 0x82 */ x86emuOp2_long_jump,
1640 /* 0x83 */ x86emuOp2_long_jump,
1641 /* 0x84 */ x86emuOp2_long_jump,
1642 /* 0x85 */ x86emuOp2_long_jump,
1643 /* 0x86 */ x86emuOp2_long_jump,
1644 /* 0x87 */ x86emuOp2_long_jump,
1645 /* 0x88 */ x86emuOp2_long_jump,
1646 /* 0x89 */ x86emuOp2_long_jump,
1647 /* 0x8a */ x86emuOp2_long_jump,
1648 /* 0x8b */ x86emuOp2_long_jump,
1649 /* 0x8c */ x86emuOp2_long_jump,
1650 /* 0x8d */ x86emuOp2_long_jump,
1651 /* 0x8e */ x86emuOp2_long_jump,
1652 /* 0x8f */ x86emuOp2_long_jump,
1654 /* 0x90 */ x86emuOp2_set_byte,
1655 /* 0x91 */ x86emuOp2_set_byte,
1656 /* 0x92 */ x86emuOp2_set_byte,
1657 /* 0x93 */ x86emuOp2_set_byte,
1658 /* 0x94 */ x86emuOp2_set_byte,
1659 /* 0x95 */ x86emuOp2_set_byte,
1660 /* 0x96 */ x86emuOp2_set_byte,
1661 /* 0x97 */ x86emuOp2_set_byte,
1662 /* 0x98 */ x86emuOp2_set_byte,
1663 /* 0x99 */ x86emuOp2_set_byte,
1664 /* 0x9a */ x86emuOp2_set_byte,
1665 /* 0x9b */ x86emuOp2_set_byte,
1666 /* 0x9c */ x86emuOp2_set_byte,
1667 /* 0x9d */ x86emuOp2_set_byte,
1668 /* 0x9e */ x86emuOp2_set_byte,
1669 /* 0x9f */ x86emuOp2_set_byte,
1671 /* 0xa0 */ x86emuOp2_push_FS,
1672 /* 0xa1 */ x86emuOp2_pop_FS,
1673 /* 0xa2 */ x86emuOp2_illegal_op,
1674 /* 0xa3 */ x86emuOp2_bt_R,
1675 /* 0xa4 */ x86emuOp2_shld_IMM,
1676 /* 0xa5 */ x86emuOp2_shld_CL,
1677 /* 0xa6 */ x86emuOp2_illegal_op,
1678 /* 0xa7 */ x86emuOp2_illegal_op,
1679 /* 0xa8 */ x86emuOp2_push_GS,
1680 /* 0xa9 */ x86emuOp2_pop_GS,
1681 /* 0xaa */ x86emuOp2_illegal_op,
1682 /* 0xab */ x86emuOp2_bt_R,
1683 /* 0xac */ x86emuOp2_shrd_IMM,
1684 /* 0xad */ x86emuOp2_shrd_CL,
1685 /* 0xae */ x86emuOp2_illegal_op,
1686 /* 0xaf */ x86emuOp2_imul_R_RM,
1688 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1689 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1690 /* 0xb2 */ x86emuOp2_lss_R_IMM,
1691 /* 0xb3 */ x86emuOp2_btr_R,
1692 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
1693 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
1694 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
1695 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
1696 /* 0xb8 */ x86emuOp2_illegal_op,
1697 /* 0xb9 */ x86emuOp2_illegal_op,
1698 /* 0xba */ x86emuOp2_btX_I,
1699 /* 0xbb */ x86emuOp2_btc_R,
1700 /* 0xbc */ x86emuOp2_bsf,
1701 /* 0xbd */ x86emuOp2_bsr,
1702 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
1703 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
1705 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
1706 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
1707 /* 0xc2 */ x86emuOp2_illegal_op,
1708 /* 0xc3 */ x86emuOp2_illegal_op,
1709 /* 0xc4 */ x86emuOp2_illegal_op,
1710 /* 0xc5 */ x86emuOp2_illegal_op,
1711 /* 0xc6 */ x86emuOp2_illegal_op,
1712 /* 0xc7 */ x86emuOp2_illegal_op,
1713 /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
1714 /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
1715 /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
1716 /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
1717 /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
1718 /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
1719 /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
1720 /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
1722 /* 0xd0 */ x86emuOp2_illegal_op,
1723 /* 0xd1 */ x86emuOp2_illegal_op,
1724 /* 0xd2 */ x86emuOp2_illegal_op,
1725 /* 0xd3 */ x86emuOp2_illegal_op,
1726 /* 0xd4 */ x86emuOp2_illegal_op,
1727 /* 0xd5 */ x86emuOp2_illegal_op,
1728 /* 0xd6 */ x86emuOp2_illegal_op,
1729 /* 0xd7 */ x86emuOp2_illegal_op,
1730 /* 0xd8 */ x86emuOp2_illegal_op,
1731 /* 0xd9 */ x86emuOp2_illegal_op,
1732 /* 0xda */ x86emuOp2_illegal_op,
1733 /* 0xdb */ x86emuOp2_illegal_op,
1734 /* 0xdc */ x86emuOp2_illegal_op,
1735 /* 0xdd */ x86emuOp2_illegal_op,
1736 /* 0xde */ x86emuOp2_illegal_op,
1737 /* 0xdf */ x86emuOp2_illegal_op,
1739 /* 0xe0 */ x86emuOp2_illegal_op,
1740 /* 0xe1 */ x86emuOp2_illegal_op,
1741 /* 0xe2 */ x86emuOp2_illegal_op,
1742 /* 0xe3 */ x86emuOp2_illegal_op,
1743 /* 0xe4 */ x86emuOp2_illegal_op,
1744 /* 0xe5 */ x86emuOp2_illegal_op,
1745 /* 0xe6 */ x86emuOp2_illegal_op,
1746 /* 0xe7 */ x86emuOp2_illegal_op,
1747 /* 0xe8 */ x86emuOp2_illegal_op,
1748 /* 0xe9 */ x86emuOp2_illegal_op,
1749 /* 0xea */ x86emuOp2_illegal_op,
1750 /* 0xeb */ x86emuOp2_illegal_op,
1751 /* 0xec */ x86emuOp2_illegal_op,
1752 /* 0xed */ x86emuOp2_illegal_op,
1753 /* 0xee */ x86emuOp2_illegal_op,
1754 /* 0xef */ x86emuOp2_illegal_op,
1756 /* 0xf0 */ x86emuOp2_illegal_op,
1757 /* 0xf1 */ x86emuOp2_illegal_op,
1758 /* 0xf2 */ x86emuOp2_illegal_op,
1759 /* 0xf3 */ x86emuOp2_illegal_op,
1760 /* 0xf4 */ x86emuOp2_illegal_op,
1761 /* 0xf5 */ x86emuOp2_illegal_op,
1762 /* 0xf6 */ x86emuOp2_illegal_op,
1763 /* 0xf7 */ x86emuOp2_illegal_op,
1764 /* 0xf8 */ x86emuOp2_illegal_op,
1765 /* 0xf9 */ x86emuOp2_illegal_op,
1766 /* 0xfa */ x86emuOp2_illegal_op,
1767 /* 0xfb */ x86emuOp2_illegal_op,
1768 /* 0xfc */ x86emuOp2_illegal_op,
1769 /* 0xfd */ x86emuOp2_illegal_op,
1770 /* 0xfe */ x86emuOp2_illegal_op,
1771 /* 0xff */ x86emuOp2_illegal_op,