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 /*----------------------------- Implementation ----------------------------*/
51 /****************************************************************************
53 op1 - Instruction op code
56 Handles illegal opcodes.
57 ****************************************************************************/
58 void x86emuOp2_illegal_op(
62 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
64 printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
65 M.x86.R_CS, M.x86.R_IP-2,op2);
70 #define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
72 /****************************************************************************
74 Handles opcode 0x0f,0x80-0x8F
75 ****************************************************************************/
76 int x86emu_check_jump_condition(u8 op)
80 DECODE_PRINTF("JO\t");
81 return ACCESS_FLAG(F_OF);
83 DECODE_PRINTF("JNO\t");
84 return !ACCESS_FLAG(F_OF);
87 DECODE_PRINTF("JB\t");
88 return ACCESS_FLAG(F_CF);
91 DECODE_PRINTF("JNB\t");
92 return !ACCESS_FLAG(F_CF);
95 DECODE_PRINTF("JZ\t");
96 return ACCESS_FLAG(F_ZF);
99 DECODE_PRINTF("JNZ\t");
100 return !ACCESS_FLAG(F_ZF);
103 DECODE_PRINTF("JBE\t");
104 return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
107 DECODE_PRINTF("JNBE\t");
108 return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
111 DECODE_PRINTF("JS\t");
112 return ACCESS_FLAG(F_SF);
115 DECODE_PRINTF("JNS\t");
116 return !ACCESS_FLAG(F_SF);
119 DECODE_PRINTF("JP\t");
120 return ACCESS_FLAG(F_PF);
123 DECODE_PRINTF("JNP\t");
124 return !ACCESS_FLAG(F_PF);
127 DECODE_PRINTF("JL\t");
128 return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
131 DECODE_PRINTF("JNL\t");
132 return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
135 DECODE_PRINTF("JLE\t");
136 return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
140 DECODE_PRINTF("JNLE\t");
141 return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
146 void x86emuOp2_long_jump(u8 op2)
151 /* conditional jump to word offset. */
153 cond = x86emu_check_jump_condition(op2 & 0xF);
154 target = (s16) fetch_word_imm();
155 target += (s16) M.x86.R_IP;
156 DECODE_PRINTF2("%04x\n", target);
159 M.x86.R_IP = (u16)target;
160 DECODE_CLEAR_SEGOVR();
164 /****************************************************************************
166 Handles opcode 0x0f,0x90-0x9F
167 ****************************************************************************/
168 void x86emuOp2_set_byte(u8 op2)
180 cond = ACCESS_FLAG(F_OF);
184 cond = !ACCESS_FLAG(F_OF);
188 cond = ACCESS_FLAG(F_CF);
192 cond = !ACCESS_FLAG(F_CF);
196 cond = ACCESS_FLAG(F_ZF);
200 cond = !ACCESS_FLAG(F_ZF);
204 cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
208 cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
212 cond = ACCESS_FLAG(F_SF);
216 cond = !ACCESS_FLAG(F_SF);
220 cond = ACCESS_FLAG(F_PF);
224 cond = !ACCESS_FLAG(F_PF);
228 cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
232 cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
236 cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
241 cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
246 FETCH_DECODE_MODRM(mod, rh, rl);
248 destoffset = decode_rmXX_address(mod, rl);
250 store_data_byte(destoffset, cond ? 0x01 : 0x00);
251 } else { /* register to register */
252 destreg = DECODE_RM_BYTE_REGISTER(rl);
254 *destreg = cond ? 0x01 : 0x00;
256 DECODE_CLEAR_SEGOVR();
260 /****************************************************************************
262 Handles opcode 0x0f,0xa0
263 ****************************************************************************/
264 void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
267 DECODE_PRINTF("PUSH\tFS\n");
269 push_word(M.x86.R_FS);
270 DECODE_CLEAR_SEGOVR();
274 /****************************************************************************
276 Handles opcode 0x0f,0xa1
277 ****************************************************************************/
278 void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
281 DECODE_PRINTF("POP\tFS\n");
283 M.x86.R_FS = pop_word();
284 DECODE_CLEAR_SEGOVR();
288 /****************************************************************************
290 Handles opcode 0x0f,0xa3
291 ****************************************************************************/
292 void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
299 DECODE_PRINTF("BT\t");
300 FETCH_DECODE_MODRM(mod, rh, rl);
302 srcoffset = decode_rmXX_address(mod, rl);
303 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
308 shiftreg = DECODE_RM_LONG_REGISTER(rh);
310 bit = *shiftreg & 0x1F;
311 disp = (s16)*shiftreg >> 5;
312 srcval = fetch_data_long(srcoffset+disp);
313 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
319 shiftreg = DECODE_RM_WORD_REGISTER(rh);
321 bit = *shiftreg & 0xF;
322 disp = (s16)*shiftreg >> 4;
323 srcval = fetch_data_word(srcoffset+disp);
324 CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
326 } else { /* register to register */
327 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
328 u32 *srcreg,*shiftreg;
330 srcreg = DECODE_RM_LONG_REGISTER(rl);
332 shiftreg = DECODE_RM_LONG_REGISTER(rh);
334 bit = *shiftreg & 0x1F;
335 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
337 u16 *srcreg,*shiftreg;
339 srcreg = DECODE_RM_WORD_REGISTER(rl);
341 shiftreg = DECODE_RM_WORD_REGISTER(rh);
343 bit = *shiftreg & 0xF;
344 CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
347 DECODE_CLEAR_SEGOVR();
351 /****************************************************************************
353 Handles opcode 0x0f,0xa4
354 ****************************************************************************/
355 void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
362 DECODE_PRINTF("SHLD\t");
363 FETCH_DECODE_MODRM(mod, rh, rl);
365 destoffset = decode_rmXX_address(mod, rl);
366 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
371 shiftreg = DECODE_RM_LONG_REGISTER(rh);
373 shift = fetch_byte_imm();
374 DECODE_PRINTF2("%d\n", shift);
376 destval = fetch_data_long(destoffset);
377 destval = shld_long(destval,*shiftreg,shift);
378 store_data_long(destoffset, destval);
384 shiftreg = DECODE_RM_WORD_REGISTER(rh);
386 shift = fetch_byte_imm();
387 DECODE_PRINTF2("%d\n", shift);
389 destval = fetch_data_word(destoffset);
390 destval = shld_word(destval,*shiftreg,shift);
391 store_data_word(destoffset, destval);
393 } else { /* register to register */
394 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
395 u32 *destreg,*shiftreg;
397 destreg = DECODE_RM_LONG_REGISTER(rl);
399 shiftreg = DECODE_RM_LONG_REGISTER(rh);
401 shift = fetch_byte_imm();
402 DECODE_PRINTF2("%d\n", shift);
404 *destreg = shld_long(*destreg,*shiftreg,shift);
406 u16 *destreg,*shiftreg;
408 destreg = DECODE_RM_WORD_REGISTER(rl);
410 shiftreg = DECODE_RM_WORD_REGISTER(rh);
412 shift = fetch_byte_imm();
413 DECODE_PRINTF2("%d\n", shift);
415 *destreg = shld_word(*destreg,*shiftreg,shift);
418 DECODE_CLEAR_SEGOVR();
422 /****************************************************************************
424 Handles opcode 0x0f,0xa5
425 ****************************************************************************/
426 void x86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2))
432 DECODE_PRINTF("SHLD\t");
433 FETCH_DECODE_MODRM(mod, rh, rl);
435 destoffset = decode_rmXX_address(mod, rl);
436 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
441 shiftreg = DECODE_RM_LONG_REGISTER(rh);
442 DECODE_PRINTF(",CL\n");
444 destval = fetch_data_long(destoffset);
445 destval = shld_long(destval,*shiftreg,M.x86.R_CL);
446 store_data_long(destoffset, destval);
452 shiftreg = DECODE_RM_WORD_REGISTER(rh);
453 DECODE_PRINTF(",CL\n");
455 destval = fetch_data_word(destoffset);
456 destval = shld_word(destval,*shiftreg,M.x86.R_CL);
457 store_data_word(destoffset, destval);
459 } else { /* register to register */
460 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
461 u32 *destreg,*shiftreg;
463 destreg = DECODE_RM_LONG_REGISTER(rl);
465 shiftreg = DECODE_RM_LONG_REGISTER(rh);
466 DECODE_PRINTF(",CL\n");
468 *destreg = shld_long(*destreg,*shiftreg,M.x86.R_CL);
470 u16 *destreg,*shiftreg;
472 destreg = DECODE_RM_WORD_REGISTER(rl);
474 shiftreg = DECODE_RM_WORD_REGISTER(rh);
475 DECODE_PRINTF(",CL\n");
477 *destreg = shld_word(*destreg,*shiftreg,M.x86.R_CL);
480 DECODE_CLEAR_SEGOVR();
484 /****************************************************************************
486 Handles opcode 0x0f,0xa8
487 ****************************************************************************/
488 void x86emuOp2_push_GS(u8 X86EMU_UNUSED(op2))
491 DECODE_PRINTF("PUSH\tGS\n");
493 push_word(M.x86.R_GS);
494 DECODE_CLEAR_SEGOVR();
498 /****************************************************************************
500 Handles opcode 0x0f,0xa9
501 ****************************************************************************/
502 void x86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2))
505 DECODE_PRINTF("POP\tGS\n");
507 M.x86.R_GS = pop_word();
508 DECODE_CLEAR_SEGOVR();
512 /****************************************************************************
514 Handles opcode 0x0f,0xaa
515 ****************************************************************************/
516 void x86emuOp2_bts_R(u8 X86EMU_UNUSED(op2))
523 DECODE_PRINTF("BTS\t");
524 FETCH_DECODE_MODRM(mod, rh, rl);
526 srcoffset = decode_rmXX_address(mod, rl);
527 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
532 shiftreg = DECODE_RM_LONG_REGISTER(rh);
534 bit = *shiftreg & 0x1F;
535 disp = (s16)*shiftreg >> 5;
536 srcval = fetch_data_long(srcoffset+disp);
538 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
539 store_data_long(srcoffset+disp, srcval | mask);
545 shiftreg = DECODE_RM_WORD_REGISTER(rh);
547 bit = *shiftreg & 0xF;
548 disp = (s16)*shiftreg >> 4;
549 srcval = fetch_data_word(srcoffset+disp);
550 mask = (u16)(0x1 << bit);
551 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
552 store_data_word(srcoffset+disp, srcval | mask);
554 } else { /* register to register */
555 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
556 u32 *srcreg,*shiftreg;
559 srcreg = DECODE_RM_LONG_REGISTER(rl);
561 shiftreg = DECODE_RM_LONG_REGISTER(rh);
563 bit = *shiftreg & 0x1F;
565 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
568 u16 *srcreg,*shiftreg;
571 srcreg = DECODE_RM_WORD_REGISTER(rl);
573 shiftreg = DECODE_RM_WORD_REGISTER(rh);
575 bit = *shiftreg & 0xF;
576 mask = (u16)(0x1 << bit);
577 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
581 DECODE_CLEAR_SEGOVR();
585 /****************************************************************************
587 Handles opcode 0x0f,0xac
588 ****************************************************************************/
589 void x86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2))
596 DECODE_PRINTF("SHLD\t");
597 FETCH_DECODE_MODRM(mod, rh, rl);
599 destoffset = decode_rmXX_address(mod, rl);
600 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
605 shiftreg = DECODE_RM_LONG_REGISTER(rh);
607 shift = fetch_byte_imm();
608 DECODE_PRINTF2("%d\n", shift);
610 destval = fetch_data_long(destoffset);
611 destval = shrd_long(destval,*shiftreg,shift);
612 store_data_long(destoffset, destval);
618 shiftreg = DECODE_RM_WORD_REGISTER(rh);
620 shift = fetch_byte_imm();
621 DECODE_PRINTF2("%d\n", shift);
623 destval = fetch_data_word(destoffset);
624 destval = shrd_word(destval,*shiftreg,shift);
625 store_data_word(destoffset, destval);
627 } else { /* register to register */
628 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
629 u32 *destreg,*shiftreg;
631 destreg = DECODE_RM_LONG_REGISTER(rl);
633 shiftreg = DECODE_RM_LONG_REGISTER(rh);
635 shift = fetch_byte_imm();
636 DECODE_PRINTF2("%d\n", shift);
638 *destreg = shrd_long(*destreg,*shiftreg,shift);
640 u16 *destreg,*shiftreg;
642 destreg = DECODE_RM_WORD_REGISTER(rl);
644 shiftreg = DECODE_RM_WORD_REGISTER(rh);
646 shift = fetch_byte_imm();
647 DECODE_PRINTF2("%d\n", shift);
649 *destreg = shrd_word(*destreg,*shiftreg,shift);
652 DECODE_CLEAR_SEGOVR();
656 /****************************************************************************
658 Handles opcode 0x0f,0xad
659 ****************************************************************************/
660 void x86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2))
666 DECODE_PRINTF("SHLD\t");
667 FETCH_DECODE_MODRM(mod, rh, rl);
669 destoffset = decode_rmXX_address(mod, rl);
671 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
675 shiftreg = DECODE_RM_LONG_REGISTER(rh);
676 DECODE_PRINTF(",CL\n");
678 destval = fetch_data_long(destoffset);
679 destval = shrd_long(destval,*shiftreg,M.x86.R_CL);
680 store_data_long(destoffset, destval);
685 shiftreg = DECODE_RM_WORD_REGISTER(rh);
686 DECODE_PRINTF(",CL\n");
688 destval = fetch_data_word(destoffset);
689 destval = shrd_word(destval,*shiftreg,M.x86.R_CL);
690 store_data_word(destoffset, destval);
692 } else { /* register to register */
693 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
694 u32 *destreg,*shiftreg;
696 destreg = DECODE_RM_LONG_REGISTER(rl);
698 shiftreg = DECODE_RM_LONG_REGISTER(rh);
699 DECODE_PRINTF(",CL\n");
701 *destreg = shrd_long(*destreg,*shiftreg,M.x86.R_CL);
703 u16 *destreg,*shiftreg;
705 destreg = DECODE_RM_WORD_REGISTER(rl);
707 shiftreg = DECODE_RM_WORD_REGISTER(rh);
708 DECODE_PRINTF(",CL\n");
710 *destreg = shrd_word(*destreg,*shiftreg,M.x86.R_CL);
713 DECODE_CLEAR_SEGOVR();
717 /****************************************************************************
719 Handles opcode 0x0f,0xaf
720 ****************************************************************************/
721 void x86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2))
727 DECODE_PRINTF("IMUL\t");
728 FETCH_DECODE_MODRM(mod, rh, rl);
730 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
735 destreg = DECODE_RM_LONG_REGISTER(rh);
737 srcoffset = decode_rmXX_address(mod, rl);
738 srcval = fetch_data_long(srcoffset);
740 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)srcval);
748 *destreg = (u32)res_lo;
754 destreg = DECODE_RM_WORD_REGISTER(rh);
756 srcoffset = decode_rmXX_address(mod, rl);
757 srcval = fetch_data_word(srcoffset);
759 res = (s16)*destreg * (s16)srcval;
769 } else { /* register to register */
770 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
771 u32 *destreg,*srcreg;
774 destreg = DECODE_RM_LONG_REGISTER(rh);
776 srcreg = DECODE_RM_LONG_REGISTER(rl);
778 imul_long_direct(&res_lo,&res_hi,(s32)*destreg,(s32)*srcreg);
786 *destreg = (u32)res_lo;
788 u16 *destreg,*srcreg;
791 destreg = DECODE_RM_WORD_REGISTER(rh);
793 srcreg = DECODE_RM_WORD_REGISTER(rl);
794 res = (s16)*destreg * (s16)*srcreg;
805 DECODE_CLEAR_SEGOVR();
809 /****************************************************************************
811 Handles opcode 0x0f,0xb2
812 ****************************************************************************/
813 void x86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2))
820 DECODE_PRINTF("LSS\t");
821 FETCH_DECODE_MODRM(mod, rh, rl);
823 dstreg = DECODE_RM_WORD_REGISTER(rh);
825 srcoffset = decode_rmXX_address(mod, rl);
828 *dstreg = fetch_data_word(srcoffset);
829 M.x86.R_SS = fetch_data_word(srcoffset + 2);
830 } else { /* register to register */
834 DECODE_CLEAR_SEGOVR();
838 /****************************************************************************
840 Handles opcode 0x0f,0xb3
841 ****************************************************************************/
842 void x86emuOp2_btr_R(u8 X86EMU_UNUSED(op2))
849 DECODE_PRINTF("BTR\t");
850 FETCH_DECODE_MODRM(mod, rh, rl);
852 srcoffset = decode_rmXX_address(mod, rl);
854 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
858 shiftreg = DECODE_RM_LONG_REGISTER(rh);
860 bit = *shiftreg & 0x1F;
861 disp = (s16)*shiftreg >> 5;
862 srcval = fetch_data_long(srcoffset+disp);
864 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
865 store_data_long(srcoffset+disp, srcval & ~mask);
870 shiftreg = DECODE_RM_WORD_REGISTER(rh);
872 bit = *shiftreg & 0xF;
873 disp = (s16)*shiftreg >> 4;
874 srcval = fetch_data_word(srcoffset+disp);
875 mask = (u16)(0x1 << bit);
876 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
877 store_data_word(srcoffset+disp, (u16)(srcval & ~mask));
879 } else { /* register to register */
880 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
881 u32 *srcreg,*shiftreg;
884 srcreg = DECODE_RM_LONG_REGISTER(rl);
886 shiftreg = DECODE_RM_LONG_REGISTER(rh);
888 bit = *shiftreg & 0x1F;
890 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
893 u16 *srcreg,*shiftreg;
896 srcreg = DECODE_RM_WORD_REGISTER(rl);
898 shiftreg = DECODE_RM_WORD_REGISTER(rh);
900 bit = *shiftreg & 0xF;
901 mask = (u16)(0x1 << bit);
902 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
906 DECODE_CLEAR_SEGOVR();
910 /****************************************************************************
912 Handles opcode 0x0f,0xb4
913 ****************************************************************************/
914 void x86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2))
921 DECODE_PRINTF("LFS\t");
922 FETCH_DECODE_MODRM(mod, rh, rl);
924 dstreg = DECODE_RM_WORD_REGISTER(rh);
926 srcoffset = decode_rmXX_address(mod, rl);
929 *dstreg = fetch_data_word(srcoffset);
930 M.x86.R_FS = fetch_data_word(srcoffset + 2);
931 } else { /* register to register */
935 DECODE_CLEAR_SEGOVR();
939 /****************************************************************************
941 Handles opcode 0x0f,0xb5
942 ****************************************************************************/
943 void x86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2))
950 DECODE_PRINTF("LGS\t");
951 FETCH_DECODE_MODRM(mod, rh, rl);
953 dstreg = DECODE_RM_WORD_REGISTER(rh);
955 srcoffset = decode_rmXX_address(mod, rl);
958 *dstreg = fetch_data_word(srcoffset);
959 M.x86.R_GS = fetch_data_word(srcoffset + 2);
960 } else { /* register to register */
964 DECODE_CLEAR_SEGOVR();
968 /****************************************************************************
970 Handles opcode 0x0f,0xb6
971 ****************************************************************************/
972 void x86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2))
978 DECODE_PRINTF("MOVZX\t");
979 FETCH_DECODE_MODRM(mod, rh, rl);
981 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
985 destreg = DECODE_RM_LONG_REGISTER(rh);
987 srcoffset = decode_rmXX_address(mod, rl);
988 srcval = fetch_data_byte(srcoffset);
996 destreg = DECODE_RM_WORD_REGISTER(rh);
998 srcoffset = decode_rmXX_address(mod, rl);
999 srcval = fetch_data_byte(srcoffset);
1000 DECODE_PRINTF("\n");
1004 } else { /* register to register */
1005 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1009 destreg = DECODE_RM_LONG_REGISTER(rh);
1011 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1012 DECODE_PRINTF("\n");
1019 destreg = DECODE_RM_WORD_REGISTER(rh);
1021 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1022 DECODE_PRINTF("\n");
1027 DECODE_CLEAR_SEGOVR();
1031 /****************************************************************************
1033 Handles opcode 0x0f,0xb7
1034 ****************************************************************************/
1035 void x86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2))
1044 DECODE_PRINTF("MOVZX\t");
1045 FETCH_DECODE_MODRM(mod, rh, rl);
1047 destreg = DECODE_RM_LONG_REGISTER(rh);
1049 srcoffset = decode_rmXX_address(mod, rl);
1050 srcval = fetch_data_word(srcoffset);
1051 DECODE_PRINTF("\n");
1054 } else { /* register to register */
1055 destreg = DECODE_RM_LONG_REGISTER(rh);
1057 srcreg = DECODE_RM_WORD_REGISTER(rl);
1058 DECODE_PRINTF("\n");
1062 DECODE_CLEAR_SEGOVR();
1066 /****************************************************************************
1068 Handles opcode 0x0f,0xba
1069 ****************************************************************************/
1070 void x86emuOp2_btX_I(u8 X86EMU_UNUSED(op2))
1078 FETCH_DECODE_MODRM(mod, rh, rl);
1081 DECODE_PRINTF("BT\t");
1084 DECODE_PRINTF("BTS\t");
1087 DECODE_PRINTF("BTR\t");
1090 DECODE_PRINTF("BTC\t");
1093 DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
1095 printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n",
1096 M.x86.R_CS, M.x86.R_IP-3,op2, (mod<<6)|(rh<<3)|rl);
1101 srcoffset = decode_rmXX_address(mod, rl);
1102 shift = fetch_byte_imm();
1103 DECODE_PRINTF2(",%d\n", shift);
1106 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1110 srcval = fetch_data_long(srcoffset);
1111 mask = (0x1 << bit);
1112 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1115 store_data_long(srcoffset, srcval | mask);
1118 store_data_long(srcoffset, srcval & ~mask);
1121 store_data_long(srcoffset, srcval ^ mask);
1130 srcval = fetch_data_word(srcoffset);
1131 mask = (0x1 << bit);
1132 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1135 store_data_word(srcoffset, srcval | mask);
1138 store_data_word(srcoffset, srcval & ~mask);
1141 store_data_word(srcoffset, srcval ^ mask);
1147 } else { /* register to register */
1148 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1152 srcreg = DECODE_RM_LONG_REGISTER(rl);
1153 shift = fetch_byte_imm();
1154 DECODE_PRINTF2(",%d\n", shift);
1157 mask = (0x1 << bit);
1158 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1176 srcreg = DECODE_RM_WORD_REGISTER(rl);
1177 shift = fetch_byte_imm();
1178 DECODE_PRINTF2(",%d\n", shift);
1181 mask = (0x1 << bit);
1182 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1198 DECODE_CLEAR_SEGOVR();
1202 /****************************************************************************
1204 Handles opcode 0x0f,0xbb
1205 ****************************************************************************/
1206 void x86emuOp2_btc_R(u8 X86EMU_UNUSED(op2))
1213 DECODE_PRINTF("BTC\t");
1214 FETCH_DECODE_MODRM(mod, rh, rl);
1216 srcoffset = decode_rmXX_address(mod, rl);
1218 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1222 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1224 bit = *shiftreg & 0x1F;
1225 disp = (s16)*shiftreg >> 5;
1226 srcval = fetch_data_long(srcoffset+disp);
1227 mask = (0x1 << bit);
1228 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1229 store_data_long(srcoffset+disp, srcval ^ mask);
1234 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1236 bit = *shiftreg & 0xF;
1237 disp = (s16)*shiftreg >> 4;
1238 srcval = fetch_data_word(srcoffset+disp);
1239 mask = (u16)(0x1 << bit);
1240 CONDITIONAL_SET_FLAG(srcval & mask,F_CF);
1241 store_data_word(srcoffset+disp, (u16)(srcval ^ mask));
1243 } else { /* register to register */
1244 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1245 u32 *srcreg,*shiftreg;
1248 srcreg = DECODE_RM_LONG_REGISTER(rl);
1250 shiftreg = DECODE_RM_LONG_REGISTER(rh);
1252 bit = *shiftreg & 0x1F;
1253 mask = (0x1 << bit);
1254 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1257 u16 *srcreg,*shiftreg;
1260 srcreg = DECODE_RM_WORD_REGISTER(rl);
1262 shiftreg = DECODE_RM_WORD_REGISTER(rh);
1264 bit = *shiftreg & 0xF;
1265 mask = (u16)(0x1 << bit);
1266 CONDITIONAL_SET_FLAG(*srcreg & mask,F_CF);
1270 DECODE_CLEAR_SEGOVR();
1274 /****************************************************************************
1276 Handles opcode 0x0f,0xbc
1277 ****************************************************************************/
1278 void x86emuOp2_bsf(u8 X86EMU_UNUSED(op2))
1284 DECODE_PRINTF("BSF\n");
1285 FETCH_DECODE_MODRM(mod, rh, rl);
1287 srcoffset = decode_rmXX_address(mod, rl);
1289 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1290 u32 srcval, *dstreg;
1292 dstreg = DECODE_RM_LONG_REGISTER(rh);
1294 srcval = fetch_data_long(srcoffset);
1295 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1296 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1297 if ((srcval >> *dstreg) & 1) break;
1299 u16 srcval, *dstreg;
1301 dstreg = DECODE_RM_WORD_REGISTER(rh);
1303 srcval = fetch_data_word(srcoffset);
1304 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1305 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1306 if ((srcval >> *dstreg) & 1) break;
1308 } else { /* register to register */
1309 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1310 u32 *srcreg, *dstreg;
1312 srcreg = DECODE_RM_LONG_REGISTER(rl);
1314 dstreg = DECODE_RM_LONG_REGISTER(rh);
1316 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1317 for(*dstreg = 0; *dstreg < 32; (*dstreg)++)
1318 if ((*srcreg >> *dstreg) & 1) break;
1320 u16 *srcreg, *dstreg;
1322 srcreg = DECODE_RM_WORD_REGISTER(rl);
1324 dstreg = DECODE_RM_WORD_REGISTER(rh);
1326 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1327 for(*dstreg = 0; *dstreg < 16; (*dstreg)++)
1328 if ((*srcreg >> *dstreg) & 1) break;
1331 DECODE_CLEAR_SEGOVR();
1335 /****************************************************************************
1337 Handles opcode 0x0f,0xbd
1338 ****************************************************************************/
1339 void x86emuOp2_bsr(u8 X86EMU_UNUSED(op2))
1345 DECODE_PRINTF("BSF\n");
1346 FETCH_DECODE_MODRM(mod, rh, rl);
1348 srcoffset = decode_rmXX_address(mod, rl);
1350 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1351 u32 srcval, *dstreg;
1353 dstreg = DECODE_RM_LONG_REGISTER(rh);
1355 srcval = fetch_data_long(srcoffset);
1356 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1357 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1358 if ((srcval >> *dstreg) & 1) break;
1360 u16 srcval, *dstreg;
1362 dstreg = DECODE_RM_WORD_REGISTER(rh);
1364 srcval = fetch_data_word(srcoffset);
1365 CONDITIONAL_SET_FLAG(srcval == 0, F_ZF);
1366 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1367 if ((srcval >> *dstreg) & 1) break;
1369 } else { /* register to register */
1370 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1371 u32 *srcreg, *dstreg;
1373 srcreg = DECODE_RM_LONG_REGISTER(rl);
1375 dstreg = DECODE_RM_LONG_REGISTER(rh);
1377 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1378 for(*dstreg = 31; *dstreg > 0; (*dstreg)--)
1379 if ((*srcreg >> *dstreg) & 1) break;
1381 u16 *srcreg, *dstreg;
1383 srcreg = DECODE_RM_WORD_REGISTER(rl);
1385 dstreg = DECODE_RM_WORD_REGISTER(rh);
1387 CONDITIONAL_SET_FLAG(*srcreg == 0, F_ZF);
1388 for(*dstreg = 15; *dstreg > 0; (*dstreg)--)
1389 if ((*srcreg >> *dstreg) & 1) break;
1392 DECODE_CLEAR_SEGOVR();
1396 /****************************************************************************
1398 Handles opcode 0x0f,0xbe
1399 ****************************************************************************/
1400 void x86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2))
1406 DECODE_PRINTF("MOVSX\t");
1407 FETCH_DECODE_MODRM(mod, rh, rl);
1409 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1413 destreg = DECODE_RM_LONG_REGISTER(rh);
1415 srcoffset = decode_rmXX_address(mod, rl);
1416 srcval = (s32)((s8)fetch_data_byte(srcoffset));
1417 DECODE_PRINTF("\n");
1424 destreg = DECODE_RM_WORD_REGISTER(rh);
1426 srcoffset = decode_rmXX_address(mod, rl);
1427 srcval = (s16)((s8)fetch_data_byte(srcoffset));
1428 DECODE_PRINTF("\n");
1432 } else { /* register to register */
1433 if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1437 destreg = DECODE_RM_LONG_REGISTER(rh);
1439 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1440 DECODE_PRINTF("\n");
1442 *destreg = (s32)((s8)*srcreg);
1447 destreg = DECODE_RM_WORD_REGISTER(rh);
1449 srcreg = DECODE_RM_BYTE_REGISTER(rl);
1450 DECODE_PRINTF("\n");
1452 *destreg = (s16)((s8)*srcreg);
1455 DECODE_CLEAR_SEGOVR();
1459 /****************************************************************************
1461 Handles opcode 0x0f,0xbf
1462 ****************************************************************************/
1463 void x86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2))
1472 DECODE_PRINTF("MOVSX\t");
1473 FETCH_DECODE_MODRM(mod, rh, rl);
1475 destreg = DECODE_RM_LONG_REGISTER(rh);
1477 srcoffset = decode_rmXX_address(mod, rl);
1478 srcval = (s32)((s16)fetch_data_word(srcoffset));
1479 DECODE_PRINTF("\n");
1482 } else { /* register to register */
1483 destreg = DECODE_RM_LONG_REGISTER(rh);
1485 srcreg = DECODE_RM_WORD_REGISTER(rl);
1486 DECODE_PRINTF("\n");
1488 *destreg = (s32)((s16)*srcreg);
1490 DECODE_CLEAR_SEGOVR();
1494 /***************************************************************************
1495 * Double byte operation code table:
1496 **************************************************************************/
1497 void (*x86emu_optab2[256])(u8) __attribute__((section(".got2"))) =
1499 /* 0x00 */ x86emuOp2_illegal_op, /* Group F (ring 0 PM) */
1500 /* 0x01 */ x86emuOp2_illegal_op, /* Group G (ring 0 PM) */
1501 /* 0x02 */ x86emuOp2_illegal_op, /* lar (ring 0 PM) */
1502 /* 0x03 */ x86emuOp2_illegal_op, /* lsl (ring 0 PM) */
1503 /* 0x04 */ x86emuOp2_illegal_op,
1504 /* 0x05 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1505 /* 0x06 */ x86emuOp2_illegal_op, /* clts (ring 0 PM) */
1506 /* 0x07 */ x86emuOp2_illegal_op, /* loadall (undocumented) */
1507 /* 0x08 */ x86emuOp2_illegal_op, /* invd (ring 0 PM) */
1508 /* 0x09 */ x86emuOp2_illegal_op, /* wbinvd (ring 0 PM) */
1509 /* 0x0a */ x86emuOp2_illegal_op,
1510 /* 0x0b */ x86emuOp2_illegal_op,
1511 /* 0x0c */ x86emuOp2_illegal_op,
1512 /* 0x0d */ x86emuOp2_illegal_op,
1513 /* 0x0e */ x86emuOp2_illegal_op,
1514 /* 0x0f */ x86emuOp2_illegal_op,
1516 /* 0x10 */ x86emuOp2_illegal_op,
1517 /* 0x11 */ x86emuOp2_illegal_op,
1518 /* 0x12 */ x86emuOp2_illegal_op,
1519 /* 0x13 */ x86emuOp2_illegal_op,
1520 /* 0x14 */ x86emuOp2_illegal_op,
1521 /* 0x15 */ x86emuOp2_illegal_op,
1522 /* 0x16 */ x86emuOp2_illegal_op,
1523 /* 0x17 */ x86emuOp2_illegal_op,
1524 /* 0x18 */ x86emuOp2_illegal_op,
1525 /* 0x19 */ x86emuOp2_illegal_op,
1526 /* 0x1a */ x86emuOp2_illegal_op,
1527 /* 0x1b */ x86emuOp2_illegal_op,
1528 /* 0x1c */ x86emuOp2_illegal_op,
1529 /* 0x1d */ x86emuOp2_illegal_op,
1530 /* 0x1e */ x86emuOp2_illegal_op,
1531 /* 0x1f */ x86emuOp2_illegal_op,
1533 /* 0x20 */ x86emuOp2_illegal_op, /* mov reg32,creg (ring 0 PM) */
1534 /* 0x21 */ x86emuOp2_illegal_op, /* mov reg32,dreg (ring 0 PM) */
1535 /* 0x22 */ x86emuOp2_illegal_op, /* mov creg,reg32 (ring 0 PM) */
1536 /* 0x23 */ x86emuOp2_illegal_op, /* mov dreg,reg32 (ring 0 PM) */
1537 /* 0x24 */ x86emuOp2_illegal_op, /* mov reg32,treg (ring 0 PM) */
1538 /* 0x25 */ x86emuOp2_illegal_op,
1539 /* 0x26 */ x86emuOp2_illegal_op, /* mov treg,reg32 (ring 0 PM) */
1540 /* 0x27 */ x86emuOp2_illegal_op,
1541 /* 0x28 */ x86emuOp2_illegal_op,
1542 /* 0x29 */ x86emuOp2_illegal_op,
1543 /* 0x2a */ x86emuOp2_illegal_op,
1544 /* 0x2b */ x86emuOp2_illegal_op,
1545 /* 0x2c */ x86emuOp2_illegal_op,
1546 /* 0x2d */ x86emuOp2_illegal_op,
1547 /* 0x2e */ x86emuOp2_illegal_op,
1548 /* 0x2f */ x86emuOp2_illegal_op,
1550 /* 0x30 */ x86emuOp2_illegal_op,
1551 /* 0x31 */ x86emuOp2_illegal_op,
1552 /* 0x32 */ x86emuOp2_illegal_op,
1553 /* 0x33 */ x86emuOp2_illegal_op,
1554 /* 0x34 */ x86emuOp2_illegal_op,
1555 /* 0x35 */ x86emuOp2_illegal_op,
1556 /* 0x36 */ x86emuOp2_illegal_op,
1557 /* 0x37 */ x86emuOp2_illegal_op,
1558 /* 0x38 */ x86emuOp2_illegal_op,
1559 /* 0x39 */ x86emuOp2_illegal_op,
1560 /* 0x3a */ x86emuOp2_illegal_op,
1561 /* 0x3b */ x86emuOp2_illegal_op,
1562 /* 0x3c */ x86emuOp2_illegal_op,
1563 /* 0x3d */ x86emuOp2_illegal_op,
1564 /* 0x3e */ x86emuOp2_illegal_op,
1565 /* 0x3f */ x86emuOp2_illegal_op,
1567 /* 0x40 */ x86emuOp2_illegal_op,
1568 /* 0x41 */ x86emuOp2_illegal_op,
1569 /* 0x42 */ x86emuOp2_illegal_op,
1570 /* 0x43 */ x86emuOp2_illegal_op,
1571 /* 0x44 */ x86emuOp2_illegal_op,
1572 /* 0x45 */ x86emuOp2_illegal_op,
1573 /* 0x46 */ x86emuOp2_illegal_op,
1574 /* 0x47 */ x86emuOp2_illegal_op,
1575 /* 0x48 */ x86emuOp2_illegal_op,
1576 /* 0x49 */ x86emuOp2_illegal_op,
1577 /* 0x4a */ x86emuOp2_illegal_op,
1578 /* 0x4b */ x86emuOp2_illegal_op,
1579 /* 0x4c */ x86emuOp2_illegal_op,
1580 /* 0x4d */ x86emuOp2_illegal_op,
1581 /* 0x4e */ x86emuOp2_illegal_op,
1582 /* 0x4f */ x86emuOp2_illegal_op,
1584 /* 0x50 */ x86emuOp2_illegal_op,
1585 /* 0x51 */ x86emuOp2_illegal_op,
1586 /* 0x52 */ x86emuOp2_illegal_op,
1587 /* 0x53 */ x86emuOp2_illegal_op,
1588 /* 0x54 */ x86emuOp2_illegal_op,
1589 /* 0x55 */ x86emuOp2_illegal_op,
1590 /* 0x56 */ x86emuOp2_illegal_op,
1591 /* 0x57 */ x86emuOp2_illegal_op,
1592 /* 0x58 */ x86emuOp2_illegal_op,
1593 /* 0x59 */ x86emuOp2_illegal_op,
1594 /* 0x5a */ x86emuOp2_illegal_op,
1595 /* 0x5b */ x86emuOp2_illegal_op,
1596 /* 0x5c */ x86emuOp2_illegal_op,
1597 /* 0x5d */ x86emuOp2_illegal_op,
1598 /* 0x5e */ x86emuOp2_illegal_op,
1599 /* 0x5f */ x86emuOp2_illegal_op,
1601 /* 0x60 */ x86emuOp2_illegal_op,
1602 /* 0x61 */ x86emuOp2_illegal_op,
1603 /* 0x62 */ x86emuOp2_illegal_op,
1604 /* 0x63 */ x86emuOp2_illegal_op,
1605 /* 0x64 */ x86emuOp2_illegal_op,
1606 /* 0x65 */ x86emuOp2_illegal_op,
1607 /* 0x66 */ x86emuOp2_illegal_op,
1608 /* 0x67 */ x86emuOp2_illegal_op,
1609 /* 0x68 */ x86emuOp2_illegal_op,
1610 /* 0x69 */ x86emuOp2_illegal_op,
1611 /* 0x6a */ x86emuOp2_illegal_op,
1612 /* 0x6b */ x86emuOp2_illegal_op,
1613 /* 0x6c */ x86emuOp2_illegal_op,
1614 /* 0x6d */ x86emuOp2_illegal_op,
1615 /* 0x6e */ x86emuOp2_illegal_op,
1616 /* 0x6f */ x86emuOp2_illegal_op,
1618 /* 0x70 */ x86emuOp2_illegal_op,
1619 /* 0x71 */ x86emuOp2_illegal_op,
1620 /* 0x72 */ x86emuOp2_illegal_op,
1621 /* 0x73 */ x86emuOp2_illegal_op,
1622 /* 0x74 */ x86emuOp2_illegal_op,
1623 /* 0x75 */ x86emuOp2_illegal_op,
1624 /* 0x76 */ x86emuOp2_illegal_op,
1625 /* 0x77 */ x86emuOp2_illegal_op,
1626 /* 0x78 */ x86emuOp2_illegal_op,
1627 /* 0x79 */ x86emuOp2_illegal_op,
1628 /* 0x7a */ x86emuOp2_illegal_op,
1629 /* 0x7b */ x86emuOp2_illegal_op,
1630 /* 0x7c */ x86emuOp2_illegal_op,
1631 /* 0x7d */ x86emuOp2_illegal_op,
1632 /* 0x7e */ x86emuOp2_illegal_op,
1633 /* 0x7f */ x86emuOp2_illegal_op,
1635 /* 0x80 */ x86emuOp2_long_jump,
1636 /* 0x81 */ x86emuOp2_long_jump,
1637 /* 0x82 */ x86emuOp2_long_jump,
1638 /* 0x83 */ x86emuOp2_long_jump,
1639 /* 0x84 */ x86emuOp2_long_jump,
1640 /* 0x85 */ x86emuOp2_long_jump,
1641 /* 0x86 */ x86emuOp2_long_jump,
1642 /* 0x87 */ x86emuOp2_long_jump,
1643 /* 0x88 */ x86emuOp2_long_jump,
1644 /* 0x89 */ x86emuOp2_long_jump,
1645 /* 0x8a */ x86emuOp2_long_jump,
1646 /* 0x8b */ x86emuOp2_long_jump,
1647 /* 0x8c */ x86emuOp2_long_jump,
1648 /* 0x8d */ x86emuOp2_long_jump,
1649 /* 0x8e */ x86emuOp2_long_jump,
1650 /* 0x8f */ x86emuOp2_long_jump,
1652 /* 0x90 */ x86emuOp2_set_byte,
1653 /* 0x91 */ x86emuOp2_set_byte,
1654 /* 0x92 */ x86emuOp2_set_byte,
1655 /* 0x93 */ x86emuOp2_set_byte,
1656 /* 0x94 */ x86emuOp2_set_byte,
1657 /* 0x95 */ x86emuOp2_set_byte,
1658 /* 0x96 */ x86emuOp2_set_byte,
1659 /* 0x97 */ x86emuOp2_set_byte,
1660 /* 0x98 */ x86emuOp2_set_byte,
1661 /* 0x99 */ x86emuOp2_set_byte,
1662 /* 0x9a */ x86emuOp2_set_byte,
1663 /* 0x9b */ x86emuOp2_set_byte,
1664 /* 0x9c */ x86emuOp2_set_byte,
1665 /* 0x9d */ x86emuOp2_set_byte,
1666 /* 0x9e */ x86emuOp2_set_byte,
1667 /* 0x9f */ x86emuOp2_set_byte,
1669 /* 0xa0 */ x86emuOp2_push_FS,
1670 /* 0xa1 */ x86emuOp2_pop_FS,
1671 /* 0xa2 */ x86emuOp2_illegal_op,
1672 /* 0xa3 */ x86emuOp2_bt_R,
1673 /* 0xa4 */ x86emuOp2_shld_IMM,
1674 /* 0xa5 */ x86emuOp2_shld_CL,
1675 /* 0xa6 */ x86emuOp2_illegal_op,
1676 /* 0xa7 */ x86emuOp2_illegal_op,
1677 /* 0xa8 */ x86emuOp2_push_GS,
1678 /* 0xa9 */ x86emuOp2_pop_GS,
1679 /* 0xaa */ x86emuOp2_illegal_op,
1680 /* 0xab */ x86emuOp2_bt_R,
1681 /* 0xac */ x86emuOp2_shrd_IMM,
1682 /* 0xad */ x86emuOp2_shrd_CL,
1683 /* 0xae */ x86emuOp2_illegal_op,
1684 /* 0xaf */ x86emuOp2_imul_R_RM,
1686 /* 0xb0 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1687 /* 0xb1 */ x86emuOp2_illegal_op, /* TODO: cmpxchg */
1688 /* 0xb2 */ x86emuOp2_lss_R_IMM,
1689 /* 0xb3 */ x86emuOp2_btr_R,
1690 /* 0xb4 */ x86emuOp2_lfs_R_IMM,
1691 /* 0xb5 */ x86emuOp2_lgs_R_IMM,
1692 /* 0xb6 */ x86emuOp2_movzx_byte_R_RM,
1693 /* 0xb7 */ x86emuOp2_movzx_word_R_RM,
1694 /* 0xb8 */ x86emuOp2_illegal_op,
1695 /* 0xb9 */ x86emuOp2_illegal_op,
1696 /* 0xba */ x86emuOp2_btX_I,
1697 /* 0xbb */ x86emuOp2_btc_R,
1698 /* 0xbc */ x86emuOp2_bsf,
1699 /* 0xbd */ x86emuOp2_bsr,
1700 /* 0xbe */ x86emuOp2_movsx_byte_R_RM,
1701 /* 0xbf */ x86emuOp2_movsx_word_R_RM,
1703 /* 0xc0 */ x86emuOp2_illegal_op, /* TODO: xadd */
1704 /* 0xc1 */ x86emuOp2_illegal_op, /* TODO: xadd */
1705 /* 0xc2 */ x86emuOp2_illegal_op,
1706 /* 0xc3 */ x86emuOp2_illegal_op,
1707 /* 0xc4 */ x86emuOp2_illegal_op,
1708 /* 0xc5 */ x86emuOp2_illegal_op,
1709 /* 0xc6 */ x86emuOp2_illegal_op,
1710 /* 0xc7 */ x86emuOp2_illegal_op,
1711 /* 0xc8 */ x86emuOp2_illegal_op, /* TODO: bswap */
1712 /* 0xc9 */ x86emuOp2_illegal_op, /* TODO: bswap */
1713 /* 0xca */ x86emuOp2_illegal_op, /* TODO: bswap */
1714 /* 0xcb */ x86emuOp2_illegal_op, /* TODO: bswap */
1715 /* 0xcc */ x86emuOp2_illegal_op, /* TODO: bswap */
1716 /* 0xcd */ x86emuOp2_illegal_op, /* TODO: bswap */
1717 /* 0xce */ x86emuOp2_illegal_op, /* TODO: bswap */
1718 /* 0xcf */ x86emuOp2_illegal_op, /* TODO: bswap */
1720 /* 0xd0 */ x86emuOp2_illegal_op,
1721 /* 0xd1 */ x86emuOp2_illegal_op,
1722 /* 0xd2 */ x86emuOp2_illegal_op,
1723 /* 0xd3 */ x86emuOp2_illegal_op,
1724 /* 0xd4 */ x86emuOp2_illegal_op,
1725 /* 0xd5 */ x86emuOp2_illegal_op,
1726 /* 0xd6 */ x86emuOp2_illegal_op,
1727 /* 0xd7 */ x86emuOp2_illegal_op,
1728 /* 0xd8 */ x86emuOp2_illegal_op,
1729 /* 0xd9 */ x86emuOp2_illegal_op,
1730 /* 0xda */ x86emuOp2_illegal_op,
1731 /* 0xdb */ x86emuOp2_illegal_op,
1732 /* 0xdc */ x86emuOp2_illegal_op,
1733 /* 0xdd */ x86emuOp2_illegal_op,
1734 /* 0xde */ x86emuOp2_illegal_op,
1735 /* 0xdf */ x86emuOp2_illegal_op,
1737 /* 0xe0 */ x86emuOp2_illegal_op,
1738 /* 0xe1 */ x86emuOp2_illegal_op,
1739 /* 0xe2 */ x86emuOp2_illegal_op,
1740 /* 0xe3 */ x86emuOp2_illegal_op,
1741 /* 0xe4 */ x86emuOp2_illegal_op,
1742 /* 0xe5 */ x86emuOp2_illegal_op,
1743 /* 0xe6 */ x86emuOp2_illegal_op,
1744 /* 0xe7 */ x86emuOp2_illegal_op,
1745 /* 0xe8 */ x86emuOp2_illegal_op,
1746 /* 0xe9 */ x86emuOp2_illegal_op,
1747 /* 0xea */ x86emuOp2_illegal_op,
1748 /* 0xeb */ x86emuOp2_illegal_op,
1749 /* 0xec */ x86emuOp2_illegal_op,
1750 /* 0xed */ x86emuOp2_illegal_op,
1751 /* 0xee */ x86emuOp2_illegal_op,
1752 /* 0xef */ x86emuOp2_illegal_op,
1754 /* 0xf0 */ x86emuOp2_illegal_op,
1755 /* 0xf1 */ x86emuOp2_illegal_op,
1756 /* 0xf2 */ x86emuOp2_illegal_op,
1757 /* 0xf3 */ x86emuOp2_illegal_op,
1758 /* 0xf4 */ x86emuOp2_illegal_op,
1759 /* 0xf5 */ x86emuOp2_illegal_op,
1760 /* 0xf6 */ x86emuOp2_illegal_op,
1761 /* 0xf7 */ x86emuOp2_illegal_op,
1762 /* 0xf8 */ x86emuOp2_illegal_op,
1763 /* 0xf9 */ x86emuOp2_illegal_op,
1764 /* 0xfa */ x86emuOp2_illegal_op,
1765 /* 0xfb */ x86emuOp2_illegal_op,
1766 /* 0xfc */ x86emuOp2_illegal_op,
1767 /* 0xfd */ x86emuOp2_illegal_op,
1768 /* 0xfe */ x86emuOp2_illegal_op,
1769 /* 0xff */ x86emuOp2_illegal_op,