105b261ecSmrg/**************************************************************************** 205b261ecSmrg* 305b261ecSmrg* Realmode X86 Emulator Library 405b261ecSmrg* 505b261ecSmrg* Copyright (C) 1996-1999 SciTech Software, Inc. 605b261ecSmrg* Copyright (C) David Mosberger-Tang 705b261ecSmrg* Copyright (C) 1999 Egbert Eich 805b261ecSmrg* 905b261ecSmrg* ======================================================================== 1005b261ecSmrg* 1105b261ecSmrg* Permission to use, copy, modify, distribute, and sell this software and 1205b261ecSmrg* its documentation for any purpose is hereby granted without fee, 1305b261ecSmrg* provided that the above copyright notice appear in all copies and that 1405b261ecSmrg* both that copyright notice and this permission notice appear in 1505b261ecSmrg* supporting documentation, and that the name of the authors not be used 1605b261ecSmrg* in advertising or publicity pertaining to distribution of the software 1705b261ecSmrg* without specific, written prior permission. The authors makes no 1805b261ecSmrg* representations about the suitability of this software for any purpose. 1905b261ecSmrg* It is provided "as is" without express or implied warranty. 2005b261ecSmrg* 2105b261ecSmrg* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 2205b261ecSmrg* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 2305b261ecSmrg* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 2405b261ecSmrg* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 2505b261ecSmrg* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 2605b261ecSmrg* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2705b261ecSmrg* PERFORMANCE OF THIS SOFTWARE. 2805b261ecSmrg* 2905b261ecSmrg* ======================================================================== 3005b261ecSmrg* 3105b261ecSmrg* Language: ANSI C 3205b261ecSmrg* Environment: Any 3305b261ecSmrg* Developer: Kendall Bennett 3405b261ecSmrg* 3505b261ecSmrg* Description: This file includes subroutines to implement the decoding 3605b261ecSmrg* and emulation of all the x86 extended two-byte processor 3705b261ecSmrg* instructions. 3805b261ecSmrg* 3905b261ecSmrg****************************************************************************/ 4005b261ecSmrg 4105b261ecSmrg#include "x86emu/x86emui.h" 4205b261ecSmrg 434642e01fSmrg#undef bswap_32 444642e01fSmrg#define bswap_32(x) (((x & 0xff000000) >> 24) | \ 454642e01fSmrg ((x & 0x00ff0000) >> 8) | \ 464642e01fSmrg ((x & 0x0000ff00) << 8) | \ 474642e01fSmrg ((x & 0x000000ff) << 24)) 484642e01fSmrg 4905b261ecSmrg/*----------------------------- Implementation ----------------------------*/ 5005b261ecSmrg 5105b261ecSmrg/**************************************************************************** 5205b261ecSmrgPARAMETERS: 5305b261ecSmrgop1 - Instruction op code 5405b261ecSmrg 5505b261ecSmrgREMARKS: 5605b261ecSmrgHandles illegal opcodes. 5705b261ecSmrg****************************************************************************/ 5835c4bbdfSmrgstatic void 5935c4bbdfSmrgx86emuOp2_illegal_op(u8 op2) 6005b261ecSmrg{ 6135c4bbdfSmrg START_OF_INSTR(); 6235c4bbdfSmrg DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 6335c4bbdfSmrg TRACE_REGS(); 6435c4bbdfSmrg printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n", 6535c4bbdfSmrg M.x86.R_CS, M.x86.R_IP - 2, op2); 6605b261ecSmrg HALT_SYS(); 6705b261ecSmrg END_OF_INSTR(); 6805b261ecSmrg} 6905b261ecSmrg 7005b261ecSmrg#define xorl(a,b) ((a) && !(b)) || (!(a) && (b)) 7105b261ecSmrg 7205b261ecSmrg/**************************************************************************** 7305b261ecSmrgREMARKS: 7405b261ecSmrgHandles opcode 0x0f,0x31 7505b261ecSmrg****************************************************************************/ 7635c4bbdfSmrgstatic void 7735c4bbdfSmrgx86emuOp2_rdtsc(u8 X86EMU_UNUSED(op2)) 7805b261ecSmrg{ 7905b261ecSmrg#ifdef __HAS_LONG_LONG__ 8005b261ecSmrg static u64 counter = 0; 8105b261ecSmrg#else 8205b261ecSmrg static u32 counter = 0; 8305b261ecSmrg#endif 8405b261ecSmrg 8505b261ecSmrg counter += 0x10000; 8605b261ecSmrg 8705b261ecSmrg /* read timestamp counter */ 8805b261ecSmrg /* 8905b261ecSmrg * Note that instead of actually trying to accurately measure this, we just 9005b261ecSmrg * increase the counter by a fixed amount every time we hit one of these 9105b261ecSmrg * instructions. Feel free to come up with a better method. 9205b261ecSmrg */ 9305b261ecSmrg START_OF_INSTR(); 9405b261ecSmrg DECODE_PRINTF("RDTSC\n"); 9505b261ecSmrg TRACE_AND_STEP(); 9605b261ecSmrg#ifdef __HAS_LONG_LONG__ 9705b261ecSmrg M.x86.R_EAX = counter & 0xffffffff; 9805b261ecSmrg M.x86.R_EDX = counter >> 32; 9905b261ecSmrg#else 10005b261ecSmrg M.x86.R_EAX = counter; 10105b261ecSmrg M.x86.R_EDX = 0; 10205b261ecSmrg#endif 10305b261ecSmrg DECODE_CLEAR_SEGOVR(); 10405b261ecSmrg END_OF_INSTR(); 10505b261ecSmrg} 10605b261ecSmrg 10705b261ecSmrg/**************************************************************************** 10805b261ecSmrgREMARKS: 10905b261ecSmrgHandles opcode 0x0f,0x80-0x8F 11005b261ecSmrg****************************************************************************/ 11135c4bbdfSmrgstatic void 11235c4bbdfSmrgx86emuOp2_long_jump(u8 op2) 11305b261ecSmrg{ 11405b261ecSmrg s32 target; 11535c4bbdfSmrg const char *name = NULL; 11605b261ecSmrg int cond = 0; 11705b261ecSmrg 11805b261ecSmrg /* conditional jump to word offset. */ 11905b261ecSmrg START_OF_INSTR(); 12005b261ecSmrg switch (op2) { 12135c4bbdfSmrg case 0x80: 12205b261ecSmrg name = "JO\t"; 12335c4bbdfSmrg cond = ACCESS_FLAG(F_OF); 12405b261ecSmrg break; 12535c4bbdfSmrg case 0x81: 12605b261ecSmrg name = "JNO\t"; 12705b261ecSmrg cond = !ACCESS_FLAG(F_OF); 12805b261ecSmrg break; 12935c4bbdfSmrg case 0x82: 13005b261ecSmrg name = "JB\t"; 13105b261ecSmrg cond = ACCESS_FLAG(F_CF); 13205b261ecSmrg break; 13335c4bbdfSmrg case 0x83: 13405b261ecSmrg name = "JNB\t"; 13505b261ecSmrg cond = !ACCESS_FLAG(F_CF); 13605b261ecSmrg break; 13735c4bbdfSmrg case 0x84: 13805b261ecSmrg name = "JZ\t"; 13905b261ecSmrg cond = ACCESS_FLAG(F_ZF); 14005b261ecSmrg break; 14135c4bbdfSmrg case 0x85: 14205b261ecSmrg name = "JNZ\t"; 14305b261ecSmrg cond = !ACCESS_FLAG(F_ZF); 14405b261ecSmrg break; 14535c4bbdfSmrg case 0x86: 14605b261ecSmrg name = "JBE\t"; 14705b261ecSmrg cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 14805b261ecSmrg break; 14935c4bbdfSmrg case 0x87: 15005b261ecSmrg name = "JNBE\t"; 15105b261ecSmrg cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 15205b261ecSmrg break; 15335c4bbdfSmrg case 0x88: 15405b261ecSmrg name = "JS\t"; 15505b261ecSmrg cond = ACCESS_FLAG(F_SF); 15605b261ecSmrg break; 15735c4bbdfSmrg case 0x89: 15805b261ecSmrg name = "JNS\t"; 15905b261ecSmrg cond = !ACCESS_FLAG(F_SF); 16005b261ecSmrg break; 16135c4bbdfSmrg case 0x8a: 16205b261ecSmrg name = "JP\t"; 16305b261ecSmrg cond = ACCESS_FLAG(F_PF); 16405b261ecSmrg break; 16535c4bbdfSmrg case 0x8b: 16605b261ecSmrg name = "JNP\t"; 16705b261ecSmrg cond = !ACCESS_FLAG(F_PF); 16805b261ecSmrg break; 16935c4bbdfSmrg case 0x8c: 17005b261ecSmrg name = "JL\t"; 17105b261ecSmrg cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 17205b261ecSmrg break; 17335c4bbdfSmrg case 0x8d: 17405b261ecSmrg name = "JNL\t"; 17505b261ecSmrg cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF))); 17605b261ecSmrg break; 17735c4bbdfSmrg case 0x8e: 17805b261ecSmrg name = "JLE\t"; 17905b261ecSmrg cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 18005b261ecSmrg ACCESS_FLAG(F_ZF)); 18105b261ecSmrg break; 18235c4bbdfSmrg case 0x8f: 18305b261ecSmrg name = "JNLE\t"; 18405b261ecSmrg cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 18505b261ecSmrg ACCESS_FLAG(F_ZF)); 18605b261ecSmrg break; 18705b261ecSmrg } 18805b261ecSmrg DECODE_PRINTF(name); 18935c4bbdfSmrg (void) name; 19005b261ecSmrg target = (s16) fetch_word_imm(); 19105b261ecSmrg target += (s16) M.x86.R_IP; 19205b261ecSmrg DECODE_PRINTF2("%04x\n", target); 19305b261ecSmrg TRACE_AND_STEP(); 19405b261ecSmrg if (cond) 19535c4bbdfSmrg M.x86.R_IP = (u16) target; 19605b261ecSmrg DECODE_CLEAR_SEGOVR(); 19705b261ecSmrg END_OF_INSTR(); 19805b261ecSmrg} 19905b261ecSmrg 20005b261ecSmrg/**************************************************************************** 20105b261ecSmrgREMARKS: 20205b261ecSmrgHandles opcode 0x0f,0x90-0x9F 20305b261ecSmrg****************************************************************************/ 20435c4bbdfSmrgstatic void 20535c4bbdfSmrgx86emuOp2_set_byte(u8 op2) 20605b261ecSmrg{ 20705b261ecSmrg int mod, rl, rh; 20805b261ecSmrg uint destoffset; 20935c4bbdfSmrg u8 *destreg; 21035c4bbdfSmrg const char *name = NULL; 21105b261ecSmrg int cond = 0; 21205b261ecSmrg 21305b261ecSmrg START_OF_INSTR(); 21405b261ecSmrg switch (op2) { 21535c4bbdfSmrg case 0x90: 21605b261ecSmrg name = "SETO\t"; 21735c4bbdfSmrg cond = ACCESS_FLAG(F_OF); 21805b261ecSmrg break; 21935c4bbdfSmrg case 0x91: 22005b261ecSmrg name = "SETNO\t"; 22105b261ecSmrg cond = !ACCESS_FLAG(F_OF); 22205b261ecSmrg break; 22335c4bbdfSmrg case 0x92: 22405b261ecSmrg name = "SETB\t"; 22505b261ecSmrg cond = ACCESS_FLAG(F_CF); 22605b261ecSmrg break; 22735c4bbdfSmrg case 0x93: 22805b261ecSmrg name = "SETNB\t"; 22905b261ecSmrg cond = !ACCESS_FLAG(F_CF); 23005b261ecSmrg break; 23135c4bbdfSmrg case 0x94: 23205b261ecSmrg name = "SETZ\t"; 23305b261ecSmrg cond = ACCESS_FLAG(F_ZF); 23405b261ecSmrg break; 23535c4bbdfSmrg case 0x95: 23605b261ecSmrg name = "SETNZ\t"; 23705b261ecSmrg cond = !ACCESS_FLAG(F_ZF); 23805b261ecSmrg break; 23935c4bbdfSmrg case 0x96: 24005b261ecSmrg name = "SETBE\t"; 24105b261ecSmrg cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF); 24205b261ecSmrg break; 24335c4bbdfSmrg case 0x97: 24405b261ecSmrg name = "SETNBE\t"; 24505b261ecSmrg cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)); 24605b261ecSmrg break; 24735c4bbdfSmrg case 0x98: 24805b261ecSmrg name = "SETS\t"; 24905b261ecSmrg cond = ACCESS_FLAG(F_SF); 25005b261ecSmrg break; 25135c4bbdfSmrg case 0x99: 25205b261ecSmrg name = "SETNS\t"; 25305b261ecSmrg cond = !ACCESS_FLAG(F_SF); 25405b261ecSmrg break; 25535c4bbdfSmrg case 0x9a: 25605b261ecSmrg name = "SETP\t"; 25705b261ecSmrg cond = ACCESS_FLAG(F_PF); 25805b261ecSmrg break; 25935c4bbdfSmrg case 0x9b: 26005b261ecSmrg name = "SETNP\t"; 26105b261ecSmrg cond = !ACCESS_FLAG(F_PF); 26205b261ecSmrg break; 26335c4bbdfSmrg case 0x9c: 26405b261ecSmrg name = "SETL\t"; 26505b261ecSmrg cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 26605b261ecSmrg break; 26735c4bbdfSmrg case 0x9d: 26805b261ecSmrg name = "SETNL\t"; 26905b261ecSmrg cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)); 27005b261ecSmrg break; 27135c4bbdfSmrg case 0x9e: 27205b261ecSmrg name = "SETLE\t"; 27305b261ecSmrg cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 27405b261ecSmrg ACCESS_FLAG(F_ZF)); 27505b261ecSmrg break; 27635c4bbdfSmrg case 0x9f: 27705b261ecSmrg name = "SETNLE\t"; 27805b261ecSmrg cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || 27905b261ecSmrg ACCESS_FLAG(F_ZF)); 28005b261ecSmrg break; 28105b261ecSmrg } 28205b261ecSmrg DECODE_PRINTF(name); 28335c4bbdfSmrg (void) name; 28405b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 28505b261ecSmrg switch (mod) { 28605b261ecSmrg case 0: 28705b261ecSmrg destoffset = decode_rm00_address(rl); 28805b261ecSmrg TRACE_AND_STEP(); 28905b261ecSmrg store_data_byte(destoffset, cond ? 0x01 : 0x00); 29005b261ecSmrg break; 29105b261ecSmrg case 1: 29205b261ecSmrg destoffset = decode_rm01_address(rl); 29305b261ecSmrg TRACE_AND_STEP(); 29405b261ecSmrg store_data_byte(destoffset, cond ? 0x01 : 0x00); 29505b261ecSmrg break; 29605b261ecSmrg case 2: 29705b261ecSmrg destoffset = decode_rm10_address(rl); 29805b261ecSmrg TRACE_AND_STEP(); 29905b261ecSmrg store_data_byte(destoffset, cond ? 0x01 : 0x00); 30005b261ecSmrg break; 30135c4bbdfSmrg case 3: /* register to register */ 30205b261ecSmrg destreg = DECODE_RM_BYTE_REGISTER(rl); 30305b261ecSmrg TRACE_AND_STEP(); 30405b261ecSmrg *destreg = cond ? 0x01 : 0x00; 30505b261ecSmrg break; 30605b261ecSmrg } 30705b261ecSmrg DECODE_CLEAR_SEGOVR(); 30805b261ecSmrg END_OF_INSTR(); 30905b261ecSmrg} 31005b261ecSmrg 31105b261ecSmrg/**************************************************************************** 31205b261ecSmrgREMARKS: 31305b261ecSmrgHandles opcode 0x0f,0xa0 31405b261ecSmrg****************************************************************************/ 31535c4bbdfSmrgstatic void 31635c4bbdfSmrgx86emuOp2_push_FS(u8 X86EMU_UNUSED(op2)) 31705b261ecSmrg{ 31805b261ecSmrg START_OF_INSTR(); 31905b261ecSmrg DECODE_PRINTF("PUSH\tFS\n"); 32005b261ecSmrg TRACE_AND_STEP(); 32105b261ecSmrg push_word(M.x86.R_FS); 32205b261ecSmrg DECODE_CLEAR_SEGOVR(); 32305b261ecSmrg END_OF_INSTR(); 32405b261ecSmrg} 32505b261ecSmrg 32605b261ecSmrg/**************************************************************************** 32705b261ecSmrgREMARKS: 32805b261ecSmrgHandles opcode 0x0f,0xa1 32905b261ecSmrg****************************************************************************/ 33035c4bbdfSmrgstatic void 33135c4bbdfSmrgx86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2)) 33205b261ecSmrg{ 33305b261ecSmrg START_OF_INSTR(); 33405b261ecSmrg DECODE_PRINTF("POP\tFS\n"); 33505b261ecSmrg TRACE_AND_STEP(); 33605b261ecSmrg M.x86.R_FS = pop_word(); 33705b261ecSmrg DECODE_CLEAR_SEGOVR(); 33805b261ecSmrg END_OF_INSTR(); 33905b261ecSmrg} 34005b261ecSmrg 3414642e01fSmrg/**************************************************************************** 3424642e01fSmrgREMARKS: CPUID takes EAX/ECX as inputs, writes EAX/EBX/ECX/EDX as output 3434642e01fSmrgHandles opcode 0x0f,0xa2 3444642e01fSmrg****************************************************************************/ 34535c4bbdfSmrgstatic void 34635c4bbdfSmrgx86emuOp2_cpuid(u8 X86EMU_UNUSED(op2)) 3474642e01fSmrg{ 3484642e01fSmrg START_OF_INSTR(); 3494642e01fSmrg DECODE_PRINTF("CPUID\n"); 3504642e01fSmrg TRACE_AND_STEP(); 3514642e01fSmrg cpuid(); 3524642e01fSmrg DECODE_CLEAR_SEGOVR(); 3534642e01fSmrg END_OF_INSTR(); 3544642e01fSmrg} 3554642e01fSmrg 35605b261ecSmrg/**************************************************************************** 35705b261ecSmrgREMARKS: 35805b261ecSmrgHandles opcode 0x0f,0xa3 35905b261ecSmrg****************************************************************************/ 36035c4bbdfSmrgstatic void 36135c4bbdfSmrgx86emuOp2_bt_R(u8 X86EMU_UNUSED(op2)) 36205b261ecSmrg{ 36305b261ecSmrg int mod, rl, rh; 36405b261ecSmrg uint srcoffset; 36535c4bbdfSmrg int bit, disp; 36605b261ecSmrg 36705b261ecSmrg START_OF_INSTR(); 36805b261ecSmrg DECODE_PRINTF("BT\t"); 36905b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 37005b261ecSmrg switch (mod) { 37105b261ecSmrg case 0: 37205b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 37305b261ecSmrg u32 srcval; 37405b261ecSmrg u32 *shiftreg; 37505b261ecSmrg 37605b261ecSmrg srcoffset = decode_rm00_address(rl); 37705b261ecSmrg DECODE_PRINTF(","); 37805b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 37905b261ecSmrg TRACE_AND_STEP(); 38005b261ecSmrg bit = *shiftreg & 0x1F; 38135c4bbdfSmrg disp = (s16) * shiftreg >> 5; 38235c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 38335c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 38435c4bbdfSmrg } 38535c4bbdfSmrg else { 38605b261ecSmrg u16 srcval; 38705b261ecSmrg u16 *shiftreg; 38805b261ecSmrg 38905b261ecSmrg srcoffset = decode_rm00_address(rl); 39005b261ecSmrg DECODE_PRINTF(","); 39105b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 39205b261ecSmrg TRACE_AND_STEP(); 39305b261ecSmrg bit = *shiftreg & 0xF; 39435c4bbdfSmrg disp = (s16) * shiftreg >> 4; 39535c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 39635c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 39705b261ecSmrg } 39805b261ecSmrg break; 39905b261ecSmrg case 1: 40005b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 40105b261ecSmrg u32 srcval; 40205b261ecSmrg u32 *shiftreg; 40305b261ecSmrg 40405b261ecSmrg srcoffset = decode_rm01_address(rl); 40505b261ecSmrg DECODE_PRINTF(","); 40605b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 40705b261ecSmrg TRACE_AND_STEP(); 40805b261ecSmrg bit = *shiftreg & 0x1F; 40935c4bbdfSmrg disp = (s16) * shiftreg >> 5; 41035c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 41135c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 41235c4bbdfSmrg } 41335c4bbdfSmrg else { 41405b261ecSmrg u16 srcval; 41505b261ecSmrg u16 *shiftreg; 41605b261ecSmrg 41705b261ecSmrg srcoffset = decode_rm01_address(rl); 41805b261ecSmrg DECODE_PRINTF(","); 41905b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 42005b261ecSmrg TRACE_AND_STEP(); 42105b261ecSmrg bit = *shiftreg & 0xF; 42235c4bbdfSmrg disp = (s16) * shiftreg >> 4; 42335c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 42435c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 42505b261ecSmrg } 42605b261ecSmrg break; 42705b261ecSmrg case 2: 42805b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 42905b261ecSmrg u32 srcval; 43005b261ecSmrg u32 *shiftreg; 43105b261ecSmrg 43205b261ecSmrg srcoffset = decode_rm10_address(rl); 43305b261ecSmrg DECODE_PRINTF(","); 43405b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 43505b261ecSmrg TRACE_AND_STEP(); 43605b261ecSmrg bit = *shiftreg & 0x1F; 43735c4bbdfSmrg disp = (s16) * shiftreg >> 5; 43835c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 43935c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 44035c4bbdfSmrg } 44135c4bbdfSmrg else { 44205b261ecSmrg u16 srcval; 44305b261ecSmrg u16 *shiftreg; 44405b261ecSmrg 44505b261ecSmrg srcoffset = decode_rm10_address(rl); 44605b261ecSmrg DECODE_PRINTF(","); 44705b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 44805b261ecSmrg TRACE_AND_STEP(); 44905b261ecSmrg bit = *shiftreg & 0xF; 45035c4bbdfSmrg disp = (s16) * shiftreg >> 4; 45135c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 45235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF); 45305b261ecSmrg } 45405b261ecSmrg break; 45535c4bbdfSmrg case 3: /* register to register */ 45605b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 45735c4bbdfSmrg u32 *srcreg, *shiftreg; 45805b261ecSmrg 45905b261ecSmrg srcreg = DECODE_RM_LONG_REGISTER(rl); 46005b261ecSmrg DECODE_PRINTF(","); 46105b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 46205b261ecSmrg TRACE_AND_STEP(); 46305b261ecSmrg bit = *shiftreg & 0x1F; 46435c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF); 46535c4bbdfSmrg } 46635c4bbdfSmrg else { 46735c4bbdfSmrg u16 *srcreg, *shiftreg; 46805b261ecSmrg 46905b261ecSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 47005b261ecSmrg DECODE_PRINTF(","); 47105b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 47205b261ecSmrg TRACE_AND_STEP(); 47305b261ecSmrg bit = *shiftreg & 0xF; 47435c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF); 47505b261ecSmrg } 47605b261ecSmrg break; 47705b261ecSmrg } 47805b261ecSmrg DECODE_CLEAR_SEGOVR(); 47905b261ecSmrg END_OF_INSTR(); 48005b261ecSmrg} 48105b261ecSmrg 48205b261ecSmrg/**************************************************************************** 48305b261ecSmrgREMARKS: 48405b261ecSmrgHandles opcode 0x0f,0xa4 48505b261ecSmrg****************************************************************************/ 48635c4bbdfSmrgstatic void 48735c4bbdfSmrgx86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2)) 48805b261ecSmrg{ 48905b261ecSmrg int mod, rl, rh; 49005b261ecSmrg uint destoffset; 49135c4bbdfSmrg u8 shift; 49205b261ecSmrg 49305b261ecSmrg START_OF_INSTR(); 49405b261ecSmrg DECODE_PRINTF("SHLD\t"); 49505b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 49605b261ecSmrg switch (mod) { 49705b261ecSmrg case 0: 49805b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 49905b261ecSmrg u32 destval; 50005b261ecSmrg u32 *shiftreg; 50105b261ecSmrg 50205b261ecSmrg destoffset = decode_rm00_address(rl); 50305b261ecSmrg DECODE_PRINTF(","); 50405b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 50505b261ecSmrg DECODE_PRINTF(","); 50605b261ecSmrg shift = fetch_byte_imm(); 50705b261ecSmrg DECODE_PRINTF2("%d\n", shift); 50805b261ecSmrg TRACE_AND_STEP(); 50905b261ecSmrg destval = fetch_data_long(destoffset); 51035c4bbdfSmrg destval = shld_long(destval, *shiftreg, shift); 51105b261ecSmrg store_data_long(destoffset, destval); 51235c4bbdfSmrg } 51335c4bbdfSmrg else { 51405b261ecSmrg u16 destval; 51505b261ecSmrg u16 *shiftreg; 51605b261ecSmrg 51705b261ecSmrg destoffset = decode_rm00_address(rl); 51805b261ecSmrg DECODE_PRINTF(","); 51905b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 52005b261ecSmrg DECODE_PRINTF(","); 52105b261ecSmrg shift = fetch_byte_imm(); 52205b261ecSmrg DECODE_PRINTF2("%d\n", shift); 52305b261ecSmrg TRACE_AND_STEP(); 52405b261ecSmrg destval = fetch_data_word(destoffset); 52535c4bbdfSmrg destval = shld_word(destval, *shiftreg, shift); 52605b261ecSmrg store_data_word(destoffset, destval); 52705b261ecSmrg } 52805b261ecSmrg break; 52905b261ecSmrg case 1: 53005b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 53105b261ecSmrg u32 destval; 53205b261ecSmrg u32 *shiftreg; 53305b261ecSmrg 53405b261ecSmrg destoffset = decode_rm01_address(rl); 53505b261ecSmrg DECODE_PRINTF(","); 53605b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 53705b261ecSmrg DECODE_PRINTF(","); 53805b261ecSmrg shift = fetch_byte_imm(); 53905b261ecSmrg DECODE_PRINTF2("%d\n", shift); 54005b261ecSmrg TRACE_AND_STEP(); 54105b261ecSmrg destval = fetch_data_long(destoffset); 54235c4bbdfSmrg destval = shld_long(destval, *shiftreg, shift); 54305b261ecSmrg store_data_long(destoffset, destval); 54435c4bbdfSmrg } 54535c4bbdfSmrg else { 54605b261ecSmrg u16 destval; 54705b261ecSmrg u16 *shiftreg; 54805b261ecSmrg 54905b261ecSmrg destoffset = decode_rm01_address(rl); 55005b261ecSmrg DECODE_PRINTF(","); 55105b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 55205b261ecSmrg DECODE_PRINTF(","); 55305b261ecSmrg shift = fetch_byte_imm(); 55405b261ecSmrg DECODE_PRINTF2("%d\n", shift); 55505b261ecSmrg TRACE_AND_STEP(); 55605b261ecSmrg destval = fetch_data_word(destoffset); 55735c4bbdfSmrg destval = shld_word(destval, *shiftreg, shift); 55805b261ecSmrg store_data_word(destoffset, destval); 55905b261ecSmrg } 56005b261ecSmrg break; 56105b261ecSmrg case 2: 56205b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 56305b261ecSmrg u32 destval; 56405b261ecSmrg u32 *shiftreg; 56505b261ecSmrg 56605b261ecSmrg destoffset = decode_rm10_address(rl); 56705b261ecSmrg DECODE_PRINTF(","); 56805b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 56905b261ecSmrg DECODE_PRINTF(","); 57005b261ecSmrg shift = fetch_byte_imm(); 57105b261ecSmrg DECODE_PRINTF2("%d\n", shift); 57205b261ecSmrg TRACE_AND_STEP(); 57305b261ecSmrg destval = fetch_data_long(destoffset); 57435c4bbdfSmrg destval = shld_long(destval, *shiftreg, shift); 57505b261ecSmrg store_data_long(destoffset, destval); 57635c4bbdfSmrg } 57735c4bbdfSmrg else { 57805b261ecSmrg u16 destval; 57905b261ecSmrg u16 *shiftreg; 58005b261ecSmrg 58105b261ecSmrg destoffset = decode_rm10_address(rl); 58205b261ecSmrg DECODE_PRINTF(","); 58305b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 58405b261ecSmrg DECODE_PRINTF(","); 58505b261ecSmrg shift = fetch_byte_imm(); 58605b261ecSmrg DECODE_PRINTF2("%d\n", shift); 58705b261ecSmrg TRACE_AND_STEP(); 58805b261ecSmrg destval = fetch_data_word(destoffset); 58935c4bbdfSmrg destval = shld_word(destval, *shiftreg, shift); 59005b261ecSmrg store_data_word(destoffset, destval); 59105b261ecSmrg } 59205b261ecSmrg break; 59335c4bbdfSmrg case 3: /* register to register */ 59405b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 59535c4bbdfSmrg u32 *destreg, *shiftreg; 59605b261ecSmrg 59705b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rl); 59805b261ecSmrg DECODE_PRINTF(","); 59905b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 60005b261ecSmrg DECODE_PRINTF(","); 60105b261ecSmrg shift = fetch_byte_imm(); 60205b261ecSmrg DECODE_PRINTF2("%d\n", shift); 60305b261ecSmrg TRACE_AND_STEP(); 60435c4bbdfSmrg *destreg = shld_long(*destreg, *shiftreg, shift); 60535c4bbdfSmrg } 60635c4bbdfSmrg else { 60735c4bbdfSmrg u16 *destreg, *shiftreg; 60805b261ecSmrg 60905b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rl); 61005b261ecSmrg DECODE_PRINTF(","); 61105b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 61205b261ecSmrg DECODE_PRINTF(","); 61305b261ecSmrg shift = fetch_byte_imm(); 61405b261ecSmrg DECODE_PRINTF2("%d\n", shift); 61505b261ecSmrg TRACE_AND_STEP(); 61635c4bbdfSmrg *destreg = shld_word(*destreg, *shiftreg, shift); 61705b261ecSmrg } 61805b261ecSmrg break; 61905b261ecSmrg } 62005b261ecSmrg DECODE_CLEAR_SEGOVR(); 62105b261ecSmrg END_OF_INSTR(); 62205b261ecSmrg} 62305b261ecSmrg 62405b261ecSmrg/**************************************************************************** 62505b261ecSmrgREMARKS: 62605b261ecSmrgHandles opcode 0x0f,0xa5 62705b261ecSmrg****************************************************************************/ 62835c4bbdfSmrgstatic void 62935c4bbdfSmrgx86emuOp2_shld_CL(u8 X86EMU_UNUSED(op2)) 63005b261ecSmrg{ 63105b261ecSmrg int mod, rl, rh; 63205b261ecSmrg uint destoffset; 63305b261ecSmrg 63405b261ecSmrg START_OF_INSTR(); 63505b261ecSmrg DECODE_PRINTF("SHLD\t"); 63605b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 63705b261ecSmrg switch (mod) { 63805b261ecSmrg case 0: 63905b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 64005b261ecSmrg u32 destval; 64105b261ecSmrg u32 *shiftreg; 64205b261ecSmrg 64305b261ecSmrg destoffset = decode_rm00_address(rl); 64405b261ecSmrg DECODE_PRINTF(","); 64505b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 64605b261ecSmrg DECODE_PRINTF(",CL\n"); 64705b261ecSmrg TRACE_AND_STEP(); 64805b261ecSmrg destval = fetch_data_long(destoffset); 64935c4bbdfSmrg destval = shld_long(destval, *shiftreg, M.x86.R_CL); 65005b261ecSmrg store_data_long(destoffset, destval); 65135c4bbdfSmrg } 65235c4bbdfSmrg else { 65305b261ecSmrg u16 destval; 65405b261ecSmrg u16 *shiftreg; 65505b261ecSmrg 65605b261ecSmrg destoffset = decode_rm00_address(rl); 65705b261ecSmrg DECODE_PRINTF(","); 65805b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 65905b261ecSmrg DECODE_PRINTF(",CL\n"); 66005b261ecSmrg TRACE_AND_STEP(); 66105b261ecSmrg destval = fetch_data_word(destoffset); 66235c4bbdfSmrg destval = shld_word(destval, *shiftreg, M.x86.R_CL); 66305b261ecSmrg store_data_word(destoffset, destval); 66405b261ecSmrg } 66505b261ecSmrg break; 66605b261ecSmrg case 1: 66705b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 66805b261ecSmrg u32 destval; 66905b261ecSmrg u32 *shiftreg; 67005b261ecSmrg 67105b261ecSmrg destoffset = decode_rm01_address(rl); 67205b261ecSmrg DECODE_PRINTF(","); 67305b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 67405b261ecSmrg DECODE_PRINTF(",CL\n"); 67505b261ecSmrg TRACE_AND_STEP(); 67605b261ecSmrg destval = fetch_data_long(destoffset); 67735c4bbdfSmrg destval = shld_long(destval, *shiftreg, M.x86.R_CL); 67805b261ecSmrg store_data_long(destoffset, destval); 67935c4bbdfSmrg } 68035c4bbdfSmrg else { 68105b261ecSmrg u16 destval; 68205b261ecSmrg u16 *shiftreg; 68305b261ecSmrg 68405b261ecSmrg destoffset = decode_rm01_address(rl); 68505b261ecSmrg DECODE_PRINTF(","); 68605b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 68705b261ecSmrg DECODE_PRINTF(",CL\n"); 68805b261ecSmrg TRACE_AND_STEP(); 68905b261ecSmrg destval = fetch_data_word(destoffset); 69035c4bbdfSmrg destval = shld_word(destval, *shiftreg, M.x86.R_CL); 69105b261ecSmrg store_data_word(destoffset, destval); 69205b261ecSmrg } 69305b261ecSmrg break; 69405b261ecSmrg case 2: 69505b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 69605b261ecSmrg u32 destval; 69705b261ecSmrg u32 *shiftreg; 69805b261ecSmrg 69905b261ecSmrg destoffset = decode_rm10_address(rl); 70005b261ecSmrg DECODE_PRINTF(","); 70105b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 70205b261ecSmrg DECODE_PRINTF(",CL\n"); 70305b261ecSmrg TRACE_AND_STEP(); 70405b261ecSmrg destval = fetch_data_long(destoffset); 70535c4bbdfSmrg destval = shld_long(destval, *shiftreg, M.x86.R_CL); 70605b261ecSmrg store_data_long(destoffset, destval); 70735c4bbdfSmrg } 70835c4bbdfSmrg else { 70905b261ecSmrg u16 destval; 71005b261ecSmrg u16 *shiftreg; 71105b261ecSmrg 71205b261ecSmrg destoffset = decode_rm10_address(rl); 71305b261ecSmrg DECODE_PRINTF(","); 71405b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 71505b261ecSmrg DECODE_PRINTF(",CL\n"); 71605b261ecSmrg TRACE_AND_STEP(); 71705b261ecSmrg destval = fetch_data_word(destoffset); 71835c4bbdfSmrg destval = shld_word(destval, *shiftreg, M.x86.R_CL); 71905b261ecSmrg store_data_word(destoffset, destval); 72005b261ecSmrg } 72105b261ecSmrg break; 72235c4bbdfSmrg case 3: /* register to register */ 72305b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 72435c4bbdfSmrg u32 *destreg, *shiftreg; 72505b261ecSmrg 72605b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rl); 72705b261ecSmrg DECODE_PRINTF(","); 72805b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 72905b261ecSmrg DECODE_PRINTF(",CL\n"); 73005b261ecSmrg TRACE_AND_STEP(); 73135c4bbdfSmrg *destreg = shld_long(*destreg, *shiftreg, M.x86.R_CL); 73235c4bbdfSmrg } 73335c4bbdfSmrg else { 73435c4bbdfSmrg u16 *destreg, *shiftreg; 73505b261ecSmrg 73605b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rl); 73705b261ecSmrg DECODE_PRINTF(","); 73805b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 73905b261ecSmrg DECODE_PRINTF(",CL\n"); 74005b261ecSmrg TRACE_AND_STEP(); 74135c4bbdfSmrg *destreg = shld_word(*destreg, *shiftreg, M.x86.R_CL); 74205b261ecSmrg } 74305b261ecSmrg break; 74405b261ecSmrg } 74505b261ecSmrg DECODE_CLEAR_SEGOVR(); 74605b261ecSmrg END_OF_INSTR(); 74705b261ecSmrg} 74805b261ecSmrg 74905b261ecSmrg/**************************************************************************** 75005b261ecSmrgREMARKS: 75105b261ecSmrgHandles opcode 0x0f,0xa8 75205b261ecSmrg****************************************************************************/ 75335c4bbdfSmrgstatic void 75435c4bbdfSmrgx86emuOp2_push_GS(u8 X86EMU_UNUSED(op2)) 75505b261ecSmrg{ 75605b261ecSmrg START_OF_INSTR(); 75705b261ecSmrg DECODE_PRINTF("PUSH\tGS\n"); 75805b261ecSmrg TRACE_AND_STEP(); 75905b261ecSmrg push_word(M.x86.R_GS); 76005b261ecSmrg DECODE_CLEAR_SEGOVR(); 76105b261ecSmrg END_OF_INSTR(); 76205b261ecSmrg} 76305b261ecSmrg 76405b261ecSmrg/**************************************************************************** 76505b261ecSmrgREMARKS: 76605b261ecSmrgHandles opcode 0x0f,0xa9 76705b261ecSmrg****************************************************************************/ 76835c4bbdfSmrgstatic void 76935c4bbdfSmrgx86emuOp2_pop_GS(u8 X86EMU_UNUSED(op2)) 77005b261ecSmrg{ 77105b261ecSmrg START_OF_INSTR(); 77205b261ecSmrg DECODE_PRINTF("POP\tGS\n"); 77305b261ecSmrg TRACE_AND_STEP(); 77405b261ecSmrg M.x86.R_GS = pop_word(); 77505b261ecSmrg DECODE_CLEAR_SEGOVR(); 77605b261ecSmrg END_OF_INSTR(); 77705b261ecSmrg} 77805b261ecSmrg 77905b261ecSmrg/**************************************************************************** 78005b261ecSmrgREMARKS: 78105b261ecSmrgHandles opcode 0x0f,0xab 78205b261ecSmrg****************************************************************************/ 78335c4bbdfSmrgstatic void 78435c4bbdfSmrgx86emuOp2_bts_R(u8 X86EMU_UNUSED(op2)) 78505b261ecSmrg{ 78605b261ecSmrg int mod, rl, rh; 78705b261ecSmrg uint srcoffset; 78835c4bbdfSmrg int bit, disp; 78905b261ecSmrg 79005b261ecSmrg START_OF_INSTR(); 79105b261ecSmrg DECODE_PRINTF("BTS\t"); 79205b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 79305b261ecSmrg switch (mod) { 79405b261ecSmrg case 0: 79505b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 79635c4bbdfSmrg u32 srcval, mask; 79705b261ecSmrg u32 *shiftreg; 79805b261ecSmrg 79905b261ecSmrg srcoffset = decode_rm00_address(rl); 80005b261ecSmrg DECODE_PRINTF(","); 80105b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 80205b261ecSmrg TRACE_AND_STEP(); 80305b261ecSmrg bit = *shiftreg & 0x1F; 80435c4bbdfSmrg disp = (s16) * shiftreg >> 5; 80535c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 80605b261ecSmrg mask = (0x1 << bit); 80735c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 80835c4bbdfSmrg store_data_long(srcoffset + disp, srcval | mask); 80935c4bbdfSmrg } 81035c4bbdfSmrg else { 81135c4bbdfSmrg u16 srcval, mask; 81205b261ecSmrg u16 *shiftreg; 81305b261ecSmrg 81405b261ecSmrg srcoffset = decode_rm00_address(rl); 81505b261ecSmrg DECODE_PRINTF(","); 81605b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 81705b261ecSmrg TRACE_AND_STEP(); 81805b261ecSmrg bit = *shiftreg & 0xF; 81935c4bbdfSmrg disp = (s16) * shiftreg >> 4; 82035c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 82135c4bbdfSmrg mask = (u16) (0x1 << bit); 82235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 82335c4bbdfSmrg store_data_word(srcoffset + disp, srcval | mask); 82405b261ecSmrg } 82505b261ecSmrg break; 82605b261ecSmrg case 1: 82705b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 82835c4bbdfSmrg u32 srcval, mask; 82905b261ecSmrg u32 *shiftreg; 83005b261ecSmrg 83105b261ecSmrg srcoffset = decode_rm01_address(rl); 83205b261ecSmrg DECODE_PRINTF(","); 83305b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 83405b261ecSmrg TRACE_AND_STEP(); 83505b261ecSmrg bit = *shiftreg & 0x1F; 83635c4bbdfSmrg disp = (s16) * shiftreg >> 5; 83735c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 83805b261ecSmrg mask = (0x1 << bit); 83935c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 84035c4bbdfSmrg store_data_long(srcoffset + disp, srcval | mask); 84135c4bbdfSmrg } 84235c4bbdfSmrg else { 84335c4bbdfSmrg u16 srcval, mask; 84405b261ecSmrg u16 *shiftreg; 84505b261ecSmrg 84605b261ecSmrg srcoffset = decode_rm01_address(rl); 84705b261ecSmrg DECODE_PRINTF(","); 84805b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 84905b261ecSmrg TRACE_AND_STEP(); 85005b261ecSmrg bit = *shiftreg & 0xF; 85135c4bbdfSmrg disp = (s16) * shiftreg >> 4; 85235c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 85335c4bbdfSmrg mask = (u16) (0x1 << bit); 85435c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 85535c4bbdfSmrg store_data_word(srcoffset + disp, srcval | mask); 85605b261ecSmrg } 85705b261ecSmrg break; 85805b261ecSmrg case 2: 85905b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 86035c4bbdfSmrg u32 srcval, mask; 86105b261ecSmrg u32 *shiftreg; 86205b261ecSmrg 86305b261ecSmrg srcoffset = decode_rm10_address(rl); 86405b261ecSmrg DECODE_PRINTF(","); 86505b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 86605b261ecSmrg TRACE_AND_STEP(); 86705b261ecSmrg bit = *shiftreg & 0x1F; 86835c4bbdfSmrg disp = (s16) * shiftreg >> 5; 86935c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 87005b261ecSmrg mask = (0x1 << bit); 87135c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 87235c4bbdfSmrg store_data_long(srcoffset + disp, srcval | mask); 87335c4bbdfSmrg } 87435c4bbdfSmrg else { 87535c4bbdfSmrg u16 srcval, mask; 87605b261ecSmrg u16 *shiftreg; 87705b261ecSmrg 87835c4bbdfSmrg srcoffset = decode_rm10_address(rl); 87935c4bbdfSmrg DECODE_PRINTF(","); 88035c4bbdfSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 88135c4bbdfSmrg TRACE_AND_STEP(); 88235c4bbdfSmrg bit = *shiftreg & 0xF; 88335c4bbdfSmrg disp = (s16) * shiftreg >> 4; 88435c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 88535c4bbdfSmrg mask = (u16) (0x1 << bit); 88635c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 88735c4bbdfSmrg store_data_word(srcoffset + disp, srcval | mask); 88835c4bbdfSmrg } 88935c4bbdfSmrg break; 89035c4bbdfSmrg case 3: /* register to register */ 89135c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 89235c4bbdfSmrg u32 *srcreg, *shiftreg; 89335c4bbdfSmrg u32 mask; 89435c4bbdfSmrg 89535c4bbdfSmrg srcreg = DECODE_RM_LONG_REGISTER(rl); 89635c4bbdfSmrg DECODE_PRINTF(","); 89735c4bbdfSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 89835c4bbdfSmrg TRACE_AND_STEP(); 89935c4bbdfSmrg bit = *shiftreg & 0x1F; 90035c4bbdfSmrg mask = (0x1 << bit); 90135c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 90235c4bbdfSmrg *srcreg |= mask; 90335c4bbdfSmrg } 90435c4bbdfSmrg else { 90535c4bbdfSmrg u16 *srcreg, *shiftreg; 90635c4bbdfSmrg u16 mask; 90735c4bbdfSmrg 90835c4bbdfSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 90935c4bbdfSmrg DECODE_PRINTF(","); 91035c4bbdfSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 91135c4bbdfSmrg TRACE_AND_STEP(); 91235c4bbdfSmrg bit = *shiftreg & 0xF; 91335c4bbdfSmrg mask = (u16) (0x1 << bit); 91435c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 91505b261ecSmrg *srcreg |= mask; 91605b261ecSmrg } 91705b261ecSmrg break; 91805b261ecSmrg } 91905b261ecSmrg DECODE_CLEAR_SEGOVR(); 92005b261ecSmrg END_OF_INSTR(); 92105b261ecSmrg} 92205b261ecSmrg 92305b261ecSmrg/**************************************************************************** 92405b261ecSmrgREMARKS: 92505b261ecSmrgHandles opcode 0x0f,0xac 92605b261ecSmrg****************************************************************************/ 92735c4bbdfSmrgstatic void 92835c4bbdfSmrgx86emuOp2_shrd_IMM(u8 X86EMU_UNUSED(op2)) 92905b261ecSmrg{ 93005b261ecSmrg int mod, rl, rh; 93105b261ecSmrg uint destoffset; 93235c4bbdfSmrg u8 shift; 93305b261ecSmrg 93405b261ecSmrg START_OF_INSTR(); 93505b261ecSmrg DECODE_PRINTF("SHLD\t"); 93605b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 93705b261ecSmrg switch (mod) { 93805b261ecSmrg case 0: 93905b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 94005b261ecSmrg u32 destval; 94105b261ecSmrg u32 *shiftreg; 94205b261ecSmrg 94305b261ecSmrg destoffset = decode_rm00_address(rl); 94405b261ecSmrg DECODE_PRINTF(","); 94505b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 94605b261ecSmrg DECODE_PRINTF(","); 94705b261ecSmrg shift = fetch_byte_imm(); 94805b261ecSmrg DECODE_PRINTF2("%d\n", shift); 94905b261ecSmrg TRACE_AND_STEP(); 95005b261ecSmrg destval = fetch_data_long(destoffset); 95135c4bbdfSmrg destval = shrd_long(destval, *shiftreg, shift); 95205b261ecSmrg store_data_long(destoffset, destval); 95335c4bbdfSmrg } 95435c4bbdfSmrg else { 95505b261ecSmrg u16 destval; 95605b261ecSmrg u16 *shiftreg; 95705b261ecSmrg 95805b261ecSmrg destoffset = decode_rm00_address(rl); 95905b261ecSmrg DECODE_PRINTF(","); 96005b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 96105b261ecSmrg DECODE_PRINTF(","); 96205b261ecSmrg shift = fetch_byte_imm(); 96305b261ecSmrg DECODE_PRINTF2("%d\n", shift); 96405b261ecSmrg TRACE_AND_STEP(); 96505b261ecSmrg destval = fetch_data_word(destoffset); 96635c4bbdfSmrg destval = shrd_word(destval, *shiftreg, shift); 96705b261ecSmrg store_data_word(destoffset, destval); 96805b261ecSmrg } 96905b261ecSmrg break; 97005b261ecSmrg case 1: 97105b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 97205b261ecSmrg u32 destval; 97305b261ecSmrg u32 *shiftreg; 97405b261ecSmrg 97505b261ecSmrg destoffset = decode_rm01_address(rl); 97605b261ecSmrg DECODE_PRINTF(","); 97705b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 97805b261ecSmrg DECODE_PRINTF(","); 97905b261ecSmrg shift = fetch_byte_imm(); 98005b261ecSmrg DECODE_PRINTF2("%d\n", shift); 98105b261ecSmrg TRACE_AND_STEP(); 98205b261ecSmrg destval = fetch_data_long(destoffset); 98335c4bbdfSmrg destval = shrd_long(destval, *shiftreg, shift); 98405b261ecSmrg store_data_long(destoffset, destval); 98535c4bbdfSmrg } 98635c4bbdfSmrg else { 98705b261ecSmrg u16 destval; 98805b261ecSmrg u16 *shiftreg; 98905b261ecSmrg 99005b261ecSmrg destoffset = decode_rm01_address(rl); 99105b261ecSmrg DECODE_PRINTF(","); 99205b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 99305b261ecSmrg DECODE_PRINTF(","); 99405b261ecSmrg shift = fetch_byte_imm(); 99505b261ecSmrg DECODE_PRINTF2("%d\n", shift); 99605b261ecSmrg TRACE_AND_STEP(); 99705b261ecSmrg destval = fetch_data_word(destoffset); 99835c4bbdfSmrg destval = shrd_word(destval, *shiftreg, shift); 99905b261ecSmrg store_data_word(destoffset, destval); 100005b261ecSmrg } 100105b261ecSmrg break; 100205b261ecSmrg case 2: 100305b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 100405b261ecSmrg u32 destval; 100505b261ecSmrg u32 *shiftreg; 100605b261ecSmrg 100705b261ecSmrg destoffset = decode_rm10_address(rl); 100805b261ecSmrg DECODE_PRINTF(","); 100905b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 101005b261ecSmrg DECODE_PRINTF(","); 101105b261ecSmrg shift = fetch_byte_imm(); 101205b261ecSmrg DECODE_PRINTF2("%d\n", shift); 101305b261ecSmrg TRACE_AND_STEP(); 101405b261ecSmrg destval = fetch_data_long(destoffset); 101535c4bbdfSmrg destval = shrd_long(destval, *shiftreg, shift); 101605b261ecSmrg store_data_long(destoffset, destval); 101735c4bbdfSmrg } 101835c4bbdfSmrg else { 101905b261ecSmrg u16 destval; 102005b261ecSmrg u16 *shiftreg; 102105b261ecSmrg 102205b261ecSmrg destoffset = decode_rm10_address(rl); 102305b261ecSmrg DECODE_PRINTF(","); 102405b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 102505b261ecSmrg DECODE_PRINTF(","); 102605b261ecSmrg shift = fetch_byte_imm(); 102705b261ecSmrg DECODE_PRINTF2("%d\n", shift); 102805b261ecSmrg TRACE_AND_STEP(); 102905b261ecSmrg destval = fetch_data_word(destoffset); 103035c4bbdfSmrg destval = shrd_word(destval, *shiftreg, shift); 103105b261ecSmrg store_data_word(destoffset, destval); 103205b261ecSmrg } 103305b261ecSmrg break; 103435c4bbdfSmrg case 3: /* register to register */ 103505b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 103635c4bbdfSmrg u32 *destreg, *shiftreg; 103705b261ecSmrg 103805b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rl); 103905b261ecSmrg DECODE_PRINTF(","); 104005b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 104105b261ecSmrg DECODE_PRINTF(","); 104205b261ecSmrg shift = fetch_byte_imm(); 104305b261ecSmrg DECODE_PRINTF2("%d\n", shift); 104405b261ecSmrg TRACE_AND_STEP(); 104535c4bbdfSmrg *destreg = shrd_long(*destreg, *shiftreg, shift); 104635c4bbdfSmrg } 104735c4bbdfSmrg else { 104835c4bbdfSmrg u16 *destreg, *shiftreg; 104905b261ecSmrg 105005b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rl); 105105b261ecSmrg DECODE_PRINTF(","); 105205b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 105305b261ecSmrg DECODE_PRINTF(","); 105405b261ecSmrg shift = fetch_byte_imm(); 105505b261ecSmrg DECODE_PRINTF2("%d\n", shift); 105605b261ecSmrg TRACE_AND_STEP(); 105735c4bbdfSmrg *destreg = shrd_word(*destreg, *shiftreg, shift); 105805b261ecSmrg } 105905b261ecSmrg break; 106005b261ecSmrg } 106105b261ecSmrg DECODE_CLEAR_SEGOVR(); 106205b261ecSmrg END_OF_INSTR(); 106305b261ecSmrg} 106405b261ecSmrg 106505b261ecSmrg/**************************************************************************** 106605b261ecSmrgREMARKS: 106705b261ecSmrgHandles opcode 0x0f,0xad 106805b261ecSmrg****************************************************************************/ 106935c4bbdfSmrgstatic void 107035c4bbdfSmrgx86emuOp2_shrd_CL(u8 X86EMU_UNUSED(op2)) 107105b261ecSmrg{ 107205b261ecSmrg int mod, rl, rh; 107305b261ecSmrg uint destoffset; 107405b261ecSmrg 107505b261ecSmrg START_OF_INSTR(); 107605b261ecSmrg DECODE_PRINTF("SHLD\t"); 107705b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 107805b261ecSmrg switch (mod) { 107905b261ecSmrg case 0: 108005b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 108105b261ecSmrg u32 destval; 108205b261ecSmrg u32 *shiftreg; 108305b261ecSmrg 108405b261ecSmrg destoffset = decode_rm00_address(rl); 108505b261ecSmrg DECODE_PRINTF(","); 108605b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 108705b261ecSmrg DECODE_PRINTF(",CL\n"); 108805b261ecSmrg TRACE_AND_STEP(); 108905b261ecSmrg destval = fetch_data_long(destoffset); 109035c4bbdfSmrg destval = shrd_long(destval, *shiftreg, M.x86.R_CL); 109105b261ecSmrg store_data_long(destoffset, destval); 109235c4bbdfSmrg } 109335c4bbdfSmrg else { 109405b261ecSmrg u16 destval; 109505b261ecSmrg u16 *shiftreg; 109605b261ecSmrg 109705b261ecSmrg destoffset = decode_rm00_address(rl); 109805b261ecSmrg DECODE_PRINTF(","); 109905b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 110005b261ecSmrg DECODE_PRINTF(",CL\n"); 110105b261ecSmrg TRACE_AND_STEP(); 110205b261ecSmrg destval = fetch_data_word(destoffset); 110335c4bbdfSmrg destval = shrd_word(destval, *shiftreg, M.x86.R_CL); 110405b261ecSmrg store_data_word(destoffset, destval); 110505b261ecSmrg } 110605b261ecSmrg break; 110705b261ecSmrg case 1: 110805b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 110905b261ecSmrg u32 destval; 111005b261ecSmrg u32 *shiftreg; 111105b261ecSmrg 111205b261ecSmrg destoffset = decode_rm01_address(rl); 111305b261ecSmrg DECODE_PRINTF(","); 111405b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 111505b261ecSmrg DECODE_PRINTF(",CL\n"); 111605b261ecSmrg TRACE_AND_STEP(); 111705b261ecSmrg destval = fetch_data_long(destoffset); 111835c4bbdfSmrg destval = shrd_long(destval, *shiftreg, M.x86.R_CL); 111905b261ecSmrg store_data_long(destoffset, destval); 112035c4bbdfSmrg } 112135c4bbdfSmrg else { 112205b261ecSmrg u16 destval; 112305b261ecSmrg u16 *shiftreg; 112405b261ecSmrg 112505b261ecSmrg destoffset = decode_rm01_address(rl); 112605b261ecSmrg DECODE_PRINTF(","); 112705b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 112805b261ecSmrg DECODE_PRINTF(",CL\n"); 112905b261ecSmrg TRACE_AND_STEP(); 113005b261ecSmrg destval = fetch_data_word(destoffset); 113135c4bbdfSmrg destval = shrd_word(destval, *shiftreg, M.x86.R_CL); 113205b261ecSmrg store_data_word(destoffset, destval); 113305b261ecSmrg } 113405b261ecSmrg break; 113505b261ecSmrg case 2: 113605b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 113705b261ecSmrg u32 destval; 113805b261ecSmrg u32 *shiftreg; 113905b261ecSmrg 114005b261ecSmrg destoffset = decode_rm10_address(rl); 114105b261ecSmrg DECODE_PRINTF(","); 114205b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 114305b261ecSmrg DECODE_PRINTF(",CL\n"); 114405b261ecSmrg TRACE_AND_STEP(); 114505b261ecSmrg destval = fetch_data_long(destoffset); 114635c4bbdfSmrg destval = shrd_long(destval, *shiftreg, M.x86.R_CL); 114705b261ecSmrg store_data_long(destoffset, destval); 114835c4bbdfSmrg } 114935c4bbdfSmrg else { 115005b261ecSmrg u16 destval; 115105b261ecSmrg u16 *shiftreg; 115205b261ecSmrg 115305b261ecSmrg destoffset = decode_rm10_address(rl); 115405b261ecSmrg DECODE_PRINTF(","); 115505b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 115605b261ecSmrg DECODE_PRINTF(",CL\n"); 115705b261ecSmrg TRACE_AND_STEP(); 115805b261ecSmrg destval = fetch_data_word(destoffset); 115935c4bbdfSmrg destval = shrd_word(destval, *shiftreg, M.x86.R_CL); 116005b261ecSmrg store_data_word(destoffset, destval); 116105b261ecSmrg } 116205b261ecSmrg break; 116335c4bbdfSmrg case 3: /* register to register */ 116405b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 116535c4bbdfSmrg u32 *destreg, *shiftreg; 116605b261ecSmrg 116705b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rl); 116805b261ecSmrg DECODE_PRINTF(","); 116905b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 117005b261ecSmrg DECODE_PRINTF(",CL\n"); 117105b261ecSmrg TRACE_AND_STEP(); 117235c4bbdfSmrg *destreg = shrd_long(*destreg, *shiftreg, M.x86.R_CL); 117335c4bbdfSmrg } 117435c4bbdfSmrg else { 117535c4bbdfSmrg u16 *destreg, *shiftreg; 117605b261ecSmrg 117705b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rl); 117805b261ecSmrg DECODE_PRINTF(","); 117905b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 118005b261ecSmrg DECODE_PRINTF(",CL\n"); 118105b261ecSmrg TRACE_AND_STEP(); 118235c4bbdfSmrg *destreg = shrd_word(*destreg, *shiftreg, M.x86.R_CL); 118305b261ecSmrg } 118405b261ecSmrg break; 118505b261ecSmrg } 118605b261ecSmrg DECODE_CLEAR_SEGOVR(); 118705b261ecSmrg END_OF_INSTR(); 118805b261ecSmrg} 118905b261ecSmrg 119005b261ecSmrg/**************************************************************************** 119105b261ecSmrgREMARKS: 119205b261ecSmrgHandles opcode 0x0f,0xaf 119305b261ecSmrg****************************************************************************/ 119435c4bbdfSmrgstatic void 119535c4bbdfSmrgx86emuOp2_imul_R_RM(u8 X86EMU_UNUSED(op2)) 119605b261ecSmrg{ 119705b261ecSmrg int mod, rl, rh; 119805b261ecSmrg uint srcoffset; 119905b261ecSmrg 120005b261ecSmrg START_OF_INSTR(); 120105b261ecSmrg DECODE_PRINTF("IMUL\t"); 120205b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 120305b261ecSmrg switch (mod) { 120405b261ecSmrg case 0: 120505b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 120605b261ecSmrg u32 *destreg; 120705b261ecSmrg u32 srcval; 120835c4bbdfSmrg u32 res_lo, res_hi; 120905b261ecSmrg 121005b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 121105b261ecSmrg DECODE_PRINTF(","); 121205b261ecSmrg srcoffset = decode_rm00_address(rl); 121305b261ecSmrg srcval = fetch_data_long(srcoffset); 121405b261ecSmrg TRACE_AND_STEP(); 121535c4bbdfSmrg imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); 121605b261ecSmrg if (res_hi != 0) { 121705b261ecSmrg SET_FLAG(F_CF); 121805b261ecSmrg SET_FLAG(F_OF); 121935c4bbdfSmrg } 122035c4bbdfSmrg else { 122105b261ecSmrg CLEAR_FLAG(F_CF); 122205b261ecSmrg CLEAR_FLAG(F_OF); 122305b261ecSmrg } 122435c4bbdfSmrg *destreg = (u32) res_lo; 122535c4bbdfSmrg } 122635c4bbdfSmrg else { 122705b261ecSmrg u16 *destreg; 122805b261ecSmrg u16 srcval; 122905b261ecSmrg u32 res; 123005b261ecSmrg 123105b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 123205b261ecSmrg DECODE_PRINTF(","); 123305b261ecSmrg srcoffset = decode_rm00_address(rl); 123405b261ecSmrg srcval = fetch_data_word(srcoffset); 123505b261ecSmrg TRACE_AND_STEP(); 123635c4bbdfSmrg res = (s16) * destreg * (s16) srcval; 123705b261ecSmrg if (res > 0xFFFF) { 123805b261ecSmrg SET_FLAG(F_CF); 123905b261ecSmrg SET_FLAG(F_OF); 124035c4bbdfSmrg } 124135c4bbdfSmrg else { 124205b261ecSmrg CLEAR_FLAG(F_CF); 124305b261ecSmrg CLEAR_FLAG(F_OF); 124405b261ecSmrg } 124535c4bbdfSmrg *destreg = (u16) res; 124605b261ecSmrg } 124705b261ecSmrg break; 124805b261ecSmrg case 1: 124905b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 125005b261ecSmrg u32 *destreg; 125105b261ecSmrg u32 srcval; 125235c4bbdfSmrg u32 res_lo, res_hi; 125305b261ecSmrg 125405b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 125505b261ecSmrg DECODE_PRINTF(","); 125605b261ecSmrg srcoffset = decode_rm01_address(rl); 125705b261ecSmrg srcval = fetch_data_long(srcoffset); 125805b261ecSmrg TRACE_AND_STEP(); 125935c4bbdfSmrg imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); 126005b261ecSmrg if (res_hi != 0) { 126105b261ecSmrg SET_FLAG(F_CF); 126205b261ecSmrg SET_FLAG(F_OF); 126335c4bbdfSmrg } 126435c4bbdfSmrg else { 126505b261ecSmrg CLEAR_FLAG(F_CF); 126605b261ecSmrg CLEAR_FLAG(F_OF); 126705b261ecSmrg } 126835c4bbdfSmrg *destreg = (u32) res_lo; 126935c4bbdfSmrg } 127035c4bbdfSmrg else { 127105b261ecSmrg u16 *destreg; 127205b261ecSmrg u16 srcval; 127305b261ecSmrg u32 res; 127405b261ecSmrg 127505b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 127605b261ecSmrg DECODE_PRINTF(","); 127705b261ecSmrg srcoffset = decode_rm01_address(rl); 127805b261ecSmrg srcval = fetch_data_word(srcoffset); 127905b261ecSmrg TRACE_AND_STEP(); 128035c4bbdfSmrg res = (s16) * destreg * (s16) srcval; 128105b261ecSmrg if (res > 0xFFFF) { 128205b261ecSmrg SET_FLAG(F_CF); 128305b261ecSmrg SET_FLAG(F_OF); 128435c4bbdfSmrg } 128535c4bbdfSmrg else { 128605b261ecSmrg CLEAR_FLAG(F_CF); 128705b261ecSmrg CLEAR_FLAG(F_OF); 128805b261ecSmrg } 128935c4bbdfSmrg *destreg = (u16) res; 129005b261ecSmrg } 129105b261ecSmrg break; 129205b261ecSmrg case 2: 129305b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 129405b261ecSmrg u32 *destreg; 129505b261ecSmrg u32 srcval; 129635c4bbdfSmrg u32 res_lo, res_hi; 129705b261ecSmrg 129805b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 129905b261ecSmrg DECODE_PRINTF(","); 130005b261ecSmrg srcoffset = decode_rm10_address(rl); 130105b261ecSmrg srcval = fetch_data_long(srcoffset); 130205b261ecSmrg TRACE_AND_STEP(); 130335c4bbdfSmrg imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) srcval); 130405b261ecSmrg if (res_hi != 0) { 130505b261ecSmrg SET_FLAG(F_CF); 130605b261ecSmrg SET_FLAG(F_OF); 130735c4bbdfSmrg } 130835c4bbdfSmrg else { 130905b261ecSmrg CLEAR_FLAG(F_CF); 131005b261ecSmrg CLEAR_FLAG(F_OF); 131105b261ecSmrg } 131235c4bbdfSmrg *destreg = (u32) res_lo; 131335c4bbdfSmrg } 131435c4bbdfSmrg else { 131505b261ecSmrg u16 *destreg; 131605b261ecSmrg u16 srcval; 131705b261ecSmrg u32 res; 131805b261ecSmrg 131905b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 132005b261ecSmrg DECODE_PRINTF(","); 132105b261ecSmrg srcoffset = decode_rm10_address(rl); 132205b261ecSmrg srcval = fetch_data_word(srcoffset); 132305b261ecSmrg TRACE_AND_STEP(); 132435c4bbdfSmrg res = (s16) * destreg * (s16) srcval; 132505b261ecSmrg if (res > 0xFFFF) { 132605b261ecSmrg SET_FLAG(F_CF); 132705b261ecSmrg SET_FLAG(F_OF); 132835c4bbdfSmrg } 132935c4bbdfSmrg else { 133005b261ecSmrg CLEAR_FLAG(F_CF); 133105b261ecSmrg CLEAR_FLAG(F_OF); 133205b261ecSmrg } 133335c4bbdfSmrg *destreg = (u16) res; 133405b261ecSmrg } 133505b261ecSmrg break; 133635c4bbdfSmrg case 3: /* register to register */ 133705b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 133835c4bbdfSmrg u32 *destreg, *srcreg; 133935c4bbdfSmrg u32 res_lo, res_hi; 134005b261ecSmrg 134105b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 134205b261ecSmrg DECODE_PRINTF(","); 134305b261ecSmrg srcreg = DECODE_RM_LONG_REGISTER(rl); 134405b261ecSmrg TRACE_AND_STEP(); 134535c4bbdfSmrg imul_long_direct(&res_lo, &res_hi, (s32) * destreg, (s32) * srcreg); 134605b261ecSmrg if (res_hi != 0) { 134705b261ecSmrg SET_FLAG(F_CF); 134805b261ecSmrg SET_FLAG(F_OF); 134935c4bbdfSmrg } 135035c4bbdfSmrg else { 135105b261ecSmrg CLEAR_FLAG(F_CF); 135205b261ecSmrg CLEAR_FLAG(F_OF); 135305b261ecSmrg } 135435c4bbdfSmrg *destreg = (u32) res_lo; 135535c4bbdfSmrg } 135635c4bbdfSmrg else { 135735c4bbdfSmrg u16 *destreg, *srcreg; 135805b261ecSmrg u32 res; 135905b261ecSmrg 136005b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 136105b261ecSmrg DECODE_PRINTF(","); 136205b261ecSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 136335c4bbdfSmrg res = (s16) * destreg * (s16) * srcreg; 136405b261ecSmrg if (res > 0xFFFF) { 136505b261ecSmrg SET_FLAG(F_CF); 136605b261ecSmrg SET_FLAG(F_OF); 136735c4bbdfSmrg } 136835c4bbdfSmrg else { 136905b261ecSmrg CLEAR_FLAG(F_CF); 137005b261ecSmrg CLEAR_FLAG(F_OF); 137105b261ecSmrg } 137235c4bbdfSmrg *destreg = (u16) res; 137305b261ecSmrg } 137405b261ecSmrg break; 137505b261ecSmrg } 137605b261ecSmrg DECODE_CLEAR_SEGOVR(); 137705b261ecSmrg END_OF_INSTR(); 137805b261ecSmrg} 137905b261ecSmrg 138005b261ecSmrg/**************************************************************************** 138105b261ecSmrgREMARKS: 138205b261ecSmrgHandles opcode 0x0f,0xb2 138305b261ecSmrg****************************************************************************/ 138435c4bbdfSmrgstatic void 138535c4bbdfSmrgx86emuOp2_lss_R_IMM(u8 X86EMU_UNUSED(op2)) 138605b261ecSmrg{ 138735c4bbdfSmrg int mod, rh, rl; 138805b261ecSmrg u16 *dstreg; 138905b261ecSmrg uint srcoffset; 139005b261ecSmrg 139105b261ecSmrg START_OF_INSTR(); 139205b261ecSmrg DECODE_PRINTF("LSS\t"); 139305b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 139405b261ecSmrg switch (mod) { 139505b261ecSmrg case 0: 139605b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 139705b261ecSmrg DECODE_PRINTF(","); 139805b261ecSmrg srcoffset = decode_rm00_address(rl); 139905b261ecSmrg DECODE_PRINTF("\n"); 140005b261ecSmrg TRACE_AND_STEP(); 140105b261ecSmrg *dstreg = fetch_data_word(srcoffset); 140205b261ecSmrg M.x86.R_SS = fetch_data_word(srcoffset + 2); 140305b261ecSmrg break; 140405b261ecSmrg case 1: 140505b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 140605b261ecSmrg DECODE_PRINTF(","); 140705b261ecSmrg srcoffset = decode_rm01_address(rl); 140805b261ecSmrg DECODE_PRINTF("\n"); 140905b261ecSmrg TRACE_AND_STEP(); 141005b261ecSmrg *dstreg = fetch_data_word(srcoffset); 141105b261ecSmrg M.x86.R_SS = fetch_data_word(srcoffset + 2); 141205b261ecSmrg break; 141305b261ecSmrg case 2: 141405b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 141505b261ecSmrg DECODE_PRINTF(","); 141605b261ecSmrg srcoffset = decode_rm10_address(rl); 141705b261ecSmrg DECODE_PRINTF("\n"); 141805b261ecSmrg TRACE_AND_STEP(); 141905b261ecSmrg *dstreg = fetch_data_word(srcoffset); 142005b261ecSmrg M.x86.R_SS = fetch_data_word(srcoffset + 2); 142105b261ecSmrg break; 142235c4bbdfSmrg case 3: /* register to register */ 142305b261ecSmrg /* UNDEFINED! */ 142405b261ecSmrg TRACE_AND_STEP(); 142505b261ecSmrg } 142605b261ecSmrg DECODE_CLEAR_SEGOVR(); 142705b261ecSmrg END_OF_INSTR(); 142805b261ecSmrg} 142905b261ecSmrg 143005b261ecSmrg/**************************************************************************** 143105b261ecSmrgREMARKS: 143205b261ecSmrgHandles opcode 0x0f,0xb3 143305b261ecSmrg****************************************************************************/ 143435c4bbdfSmrgstatic void 143535c4bbdfSmrgx86emuOp2_btr_R(u8 X86EMU_UNUSED(op2)) 143605b261ecSmrg{ 143735c4bbdfSmrg int mod, rl, rh; 143835c4bbdfSmrg uint srcoffset; 143935c4bbdfSmrg int bit, disp; 144035c4bbdfSmrg 144135c4bbdfSmrg START_OF_INSTR(); 144235c4bbdfSmrg DECODE_PRINTF("BTR\t"); 144335c4bbdfSmrg FETCH_DECODE_MODRM(mod, rh, rl); 144435c4bbdfSmrg switch (mod) { 144535c4bbdfSmrg case 0: 144635c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 144735c4bbdfSmrg u32 srcval, mask; 144835c4bbdfSmrg u32 *shiftreg; 144935c4bbdfSmrg 145035c4bbdfSmrg srcoffset = decode_rm00_address(rl); 145135c4bbdfSmrg DECODE_PRINTF(","); 145235c4bbdfSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 145335c4bbdfSmrg TRACE_AND_STEP(); 145435c4bbdfSmrg bit = *shiftreg & 0x1F; 145535c4bbdfSmrg disp = (s16) * shiftreg >> 5; 145635c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 145735c4bbdfSmrg mask = (0x1 << bit); 145835c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 145935c4bbdfSmrg store_data_long(srcoffset + disp, srcval & ~mask); 146035c4bbdfSmrg } 146135c4bbdfSmrg else { 146235c4bbdfSmrg u16 srcval, mask; 146335c4bbdfSmrg u16 *shiftreg; 146435c4bbdfSmrg 146535c4bbdfSmrg srcoffset = decode_rm00_address(rl); 146635c4bbdfSmrg DECODE_PRINTF(","); 146735c4bbdfSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 146835c4bbdfSmrg TRACE_AND_STEP(); 146935c4bbdfSmrg bit = *shiftreg & 0xF; 147035c4bbdfSmrg disp = (s16) * shiftreg >> 4; 147135c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 147235c4bbdfSmrg mask = (u16) (0x1 << bit); 147335c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 147435c4bbdfSmrg store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); 147535c4bbdfSmrg } 147635c4bbdfSmrg break; 147735c4bbdfSmrg case 1: 147835c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 147935c4bbdfSmrg u32 srcval, mask; 148035c4bbdfSmrg u32 *shiftreg; 148135c4bbdfSmrg 148235c4bbdfSmrg srcoffset = decode_rm01_address(rl); 148335c4bbdfSmrg DECODE_PRINTF(","); 148435c4bbdfSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 148535c4bbdfSmrg TRACE_AND_STEP(); 148635c4bbdfSmrg bit = *shiftreg & 0x1F; 148735c4bbdfSmrg disp = (s16) * shiftreg >> 5; 148835c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 148935c4bbdfSmrg mask = (0x1 << bit); 149035c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 149135c4bbdfSmrg store_data_long(srcoffset + disp, srcval & ~mask); 149235c4bbdfSmrg } 149335c4bbdfSmrg else { 149435c4bbdfSmrg u16 srcval, mask; 149535c4bbdfSmrg u16 *shiftreg; 149635c4bbdfSmrg 149735c4bbdfSmrg srcoffset = decode_rm01_address(rl); 149835c4bbdfSmrg DECODE_PRINTF(","); 149935c4bbdfSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 150035c4bbdfSmrg TRACE_AND_STEP(); 150135c4bbdfSmrg bit = *shiftreg & 0xF; 150235c4bbdfSmrg disp = (s16) * shiftreg >> 4; 150335c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 150435c4bbdfSmrg mask = (u16) (0x1 << bit); 150535c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 150635c4bbdfSmrg store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); 150735c4bbdfSmrg } 150835c4bbdfSmrg break; 150935c4bbdfSmrg case 2: 151035c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 151135c4bbdfSmrg u32 srcval, mask; 151235c4bbdfSmrg u32 *shiftreg; 151335c4bbdfSmrg 151435c4bbdfSmrg srcoffset = decode_rm10_address(rl); 151535c4bbdfSmrg DECODE_PRINTF(","); 151635c4bbdfSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 151735c4bbdfSmrg TRACE_AND_STEP(); 151835c4bbdfSmrg bit = *shiftreg & 0x1F; 151935c4bbdfSmrg disp = (s16) * shiftreg >> 5; 152035c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 152135c4bbdfSmrg mask = (0x1 << bit); 152235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 152335c4bbdfSmrg store_data_long(srcoffset + disp, srcval & ~mask); 152435c4bbdfSmrg } 152535c4bbdfSmrg else { 152635c4bbdfSmrg u16 srcval, mask; 152735c4bbdfSmrg u16 *shiftreg; 152835c4bbdfSmrg 152935c4bbdfSmrg srcoffset = decode_rm10_address(rl); 153035c4bbdfSmrg DECODE_PRINTF(","); 153135c4bbdfSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 153235c4bbdfSmrg TRACE_AND_STEP(); 153335c4bbdfSmrg bit = *shiftreg & 0xF; 153435c4bbdfSmrg disp = (s16) * shiftreg >> 4; 153535c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 153635c4bbdfSmrg mask = (u16) (0x1 << bit); 153735c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 153835c4bbdfSmrg store_data_word(srcoffset + disp, (u16) (srcval & ~mask)); 153935c4bbdfSmrg } 154035c4bbdfSmrg break; 154135c4bbdfSmrg case 3: /* register to register */ 154235c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 154335c4bbdfSmrg u32 *srcreg, *shiftreg; 154435c4bbdfSmrg u32 mask; 154535c4bbdfSmrg 154635c4bbdfSmrg srcreg = DECODE_RM_LONG_REGISTER(rl); 154735c4bbdfSmrg DECODE_PRINTF(","); 154835c4bbdfSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 154935c4bbdfSmrg TRACE_AND_STEP(); 155035c4bbdfSmrg bit = *shiftreg & 0x1F; 155135c4bbdfSmrg mask = (0x1 << bit); 155235c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 155335c4bbdfSmrg *srcreg &= ~mask; 155435c4bbdfSmrg } 155535c4bbdfSmrg else { 155635c4bbdfSmrg u16 *srcreg, *shiftreg; 155735c4bbdfSmrg u16 mask; 155835c4bbdfSmrg 155935c4bbdfSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 156035c4bbdfSmrg DECODE_PRINTF(","); 156135c4bbdfSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 156235c4bbdfSmrg TRACE_AND_STEP(); 156335c4bbdfSmrg bit = *shiftreg & 0xF; 156435c4bbdfSmrg mask = (u16) (0x1 << bit); 156535c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 156635c4bbdfSmrg *srcreg &= ~mask; 156735c4bbdfSmrg } 156835c4bbdfSmrg break; 156935c4bbdfSmrg } 157035c4bbdfSmrg DECODE_CLEAR_SEGOVR(); 157135c4bbdfSmrg END_OF_INSTR(); 157205b261ecSmrg} 157305b261ecSmrg 157405b261ecSmrg/**************************************************************************** 157505b261ecSmrgREMARKS: 157605b261ecSmrgHandles opcode 0x0f,0xb4 157705b261ecSmrg****************************************************************************/ 157835c4bbdfSmrgstatic void 157935c4bbdfSmrgx86emuOp2_lfs_R_IMM(u8 X86EMU_UNUSED(op2)) 158005b261ecSmrg{ 158135c4bbdfSmrg int mod, rh, rl; 158205b261ecSmrg u16 *dstreg; 158305b261ecSmrg uint srcoffset; 158405b261ecSmrg 158505b261ecSmrg START_OF_INSTR(); 158605b261ecSmrg DECODE_PRINTF("LFS\t"); 158705b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 158805b261ecSmrg switch (mod) { 158905b261ecSmrg case 0: 159005b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 159105b261ecSmrg DECODE_PRINTF(","); 159205b261ecSmrg srcoffset = decode_rm00_address(rl); 159305b261ecSmrg DECODE_PRINTF("\n"); 159405b261ecSmrg TRACE_AND_STEP(); 159505b261ecSmrg *dstreg = fetch_data_word(srcoffset); 159605b261ecSmrg M.x86.R_FS = fetch_data_word(srcoffset + 2); 159705b261ecSmrg break; 159805b261ecSmrg case 1: 159905b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 160005b261ecSmrg DECODE_PRINTF(","); 160105b261ecSmrg srcoffset = decode_rm01_address(rl); 160205b261ecSmrg DECODE_PRINTF("\n"); 160305b261ecSmrg TRACE_AND_STEP(); 160405b261ecSmrg *dstreg = fetch_data_word(srcoffset); 160505b261ecSmrg M.x86.R_FS = fetch_data_word(srcoffset + 2); 160605b261ecSmrg break; 160705b261ecSmrg case 2: 160805b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 160905b261ecSmrg DECODE_PRINTF(","); 161005b261ecSmrg srcoffset = decode_rm10_address(rl); 161105b261ecSmrg DECODE_PRINTF("\n"); 161205b261ecSmrg TRACE_AND_STEP(); 161305b261ecSmrg *dstreg = fetch_data_word(srcoffset); 161405b261ecSmrg M.x86.R_FS = fetch_data_word(srcoffset + 2); 161505b261ecSmrg break; 161635c4bbdfSmrg case 3: /* register to register */ 161705b261ecSmrg /* UNDEFINED! */ 161805b261ecSmrg TRACE_AND_STEP(); 161905b261ecSmrg } 162005b261ecSmrg DECODE_CLEAR_SEGOVR(); 162105b261ecSmrg END_OF_INSTR(); 162205b261ecSmrg} 162305b261ecSmrg 162405b261ecSmrg/**************************************************************************** 162505b261ecSmrgREMARKS: 162605b261ecSmrgHandles opcode 0x0f,0xb5 162705b261ecSmrg****************************************************************************/ 162835c4bbdfSmrgstatic void 162935c4bbdfSmrgx86emuOp2_lgs_R_IMM(u8 X86EMU_UNUSED(op2)) 163005b261ecSmrg{ 163135c4bbdfSmrg int mod, rh, rl; 163205b261ecSmrg u16 *dstreg; 163305b261ecSmrg uint srcoffset; 163405b261ecSmrg 163505b261ecSmrg START_OF_INSTR(); 163605b261ecSmrg DECODE_PRINTF("LGS\t"); 163705b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 163805b261ecSmrg switch (mod) { 163905b261ecSmrg case 0: 164005b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 164105b261ecSmrg DECODE_PRINTF(","); 164205b261ecSmrg srcoffset = decode_rm00_address(rl); 164305b261ecSmrg DECODE_PRINTF("\n"); 164405b261ecSmrg TRACE_AND_STEP(); 164505b261ecSmrg *dstreg = fetch_data_word(srcoffset); 164605b261ecSmrg M.x86.R_GS = fetch_data_word(srcoffset + 2); 164705b261ecSmrg break; 164805b261ecSmrg case 1: 164905b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 165005b261ecSmrg DECODE_PRINTF(","); 165105b261ecSmrg srcoffset = decode_rm01_address(rl); 165205b261ecSmrg DECODE_PRINTF("\n"); 165305b261ecSmrg TRACE_AND_STEP(); 165405b261ecSmrg *dstreg = fetch_data_word(srcoffset); 165505b261ecSmrg M.x86.R_GS = fetch_data_word(srcoffset + 2); 165605b261ecSmrg break; 165705b261ecSmrg case 2: 165805b261ecSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 165905b261ecSmrg DECODE_PRINTF(","); 166005b261ecSmrg srcoffset = decode_rm10_address(rl); 166105b261ecSmrg DECODE_PRINTF("\n"); 166205b261ecSmrg TRACE_AND_STEP(); 166305b261ecSmrg *dstreg = fetch_data_word(srcoffset); 166405b261ecSmrg M.x86.R_GS = fetch_data_word(srcoffset + 2); 166505b261ecSmrg break; 166635c4bbdfSmrg case 3: /* register to register */ 166705b261ecSmrg /* UNDEFINED! */ 166805b261ecSmrg TRACE_AND_STEP(); 166905b261ecSmrg } 167005b261ecSmrg DECODE_CLEAR_SEGOVR(); 167105b261ecSmrg END_OF_INSTR(); 167205b261ecSmrg} 167305b261ecSmrg 167405b261ecSmrg/**************************************************************************** 167505b261ecSmrgREMARKS: 167605b261ecSmrgHandles opcode 0x0f,0xb6 167705b261ecSmrg****************************************************************************/ 167835c4bbdfSmrgstatic void 167935c4bbdfSmrgx86emuOp2_movzx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 168005b261ecSmrg{ 168105b261ecSmrg int mod, rl, rh; 168205b261ecSmrg uint srcoffset; 168305b261ecSmrg 168405b261ecSmrg START_OF_INSTR(); 168505b261ecSmrg DECODE_PRINTF("MOVZX\t"); 168605b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 168705b261ecSmrg switch (mod) { 168805b261ecSmrg case 0: 168905b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 169005b261ecSmrg u32 *destreg; 169105b261ecSmrg u32 srcval; 169205b261ecSmrg 169305b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 169405b261ecSmrg DECODE_PRINTF(","); 169505b261ecSmrg srcoffset = decode_rm00_address(rl); 169605b261ecSmrg srcval = fetch_data_byte(srcoffset); 169705b261ecSmrg DECODE_PRINTF("\n"); 169805b261ecSmrg TRACE_AND_STEP(); 169905b261ecSmrg *destreg = srcval; 170035c4bbdfSmrg } 170135c4bbdfSmrg else { 170205b261ecSmrg u16 *destreg; 170305b261ecSmrg u16 srcval; 170405b261ecSmrg 170505b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 170605b261ecSmrg DECODE_PRINTF(","); 170705b261ecSmrg srcoffset = decode_rm00_address(rl); 170805b261ecSmrg srcval = fetch_data_byte(srcoffset); 170905b261ecSmrg DECODE_PRINTF("\n"); 171005b261ecSmrg TRACE_AND_STEP(); 171105b261ecSmrg *destreg = srcval; 171205b261ecSmrg } 171305b261ecSmrg break; 171405b261ecSmrg case 1: 171505b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 171605b261ecSmrg u32 *destreg; 171705b261ecSmrg u32 srcval; 171805b261ecSmrg 171905b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 172005b261ecSmrg DECODE_PRINTF(","); 172105b261ecSmrg srcoffset = decode_rm01_address(rl); 172205b261ecSmrg srcval = fetch_data_byte(srcoffset); 172305b261ecSmrg DECODE_PRINTF("\n"); 172405b261ecSmrg TRACE_AND_STEP(); 172505b261ecSmrg *destreg = srcval; 172635c4bbdfSmrg } 172735c4bbdfSmrg else { 172805b261ecSmrg u16 *destreg; 172905b261ecSmrg u16 srcval; 173005b261ecSmrg 173105b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 173205b261ecSmrg DECODE_PRINTF(","); 173305b261ecSmrg srcoffset = decode_rm01_address(rl); 173405b261ecSmrg srcval = fetch_data_byte(srcoffset); 173505b261ecSmrg DECODE_PRINTF("\n"); 173605b261ecSmrg TRACE_AND_STEP(); 173705b261ecSmrg *destreg = srcval; 173805b261ecSmrg } 173905b261ecSmrg break; 174005b261ecSmrg case 2: 174105b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 174205b261ecSmrg u32 *destreg; 174305b261ecSmrg u32 srcval; 174405b261ecSmrg 174505b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 174605b261ecSmrg DECODE_PRINTF(","); 174705b261ecSmrg srcoffset = decode_rm10_address(rl); 174805b261ecSmrg srcval = fetch_data_byte(srcoffset); 174905b261ecSmrg DECODE_PRINTF("\n"); 175005b261ecSmrg TRACE_AND_STEP(); 175105b261ecSmrg *destreg = srcval; 175235c4bbdfSmrg } 175335c4bbdfSmrg else { 175405b261ecSmrg u16 *destreg; 175505b261ecSmrg u16 srcval; 175605b261ecSmrg 175705b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 175805b261ecSmrg DECODE_PRINTF(","); 175905b261ecSmrg srcoffset = decode_rm10_address(rl); 176005b261ecSmrg srcval = fetch_data_byte(srcoffset); 176105b261ecSmrg DECODE_PRINTF("\n"); 176205b261ecSmrg TRACE_AND_STEP(); 176305b261ecSmrg *destreg = srcval; 176405b261ecSmrg } 176505b261ecSmrg break; 176635c4bbdfSmrg case 3: /* register to register */ 176705b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 176805b261ecSmrg u32 *destreg; 176935c4bbdfSmrg u8 *srcreg; 177005b261ecSmrg 177105b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 177205b261ecSmrg DECODE_PRINTF(","); 177305b261ecSmrg srcreg = DECODE_RM_BYTE_REGISTER(rl); 177405b261ecSmrg DECODE_PRINTF("\n"); 177505b261ecSmrg TRACE_AND_STEP(); 177605b261ecSmrg *destreg = *srcreg; 177735c4bbdfSmrg } 177835c4bbdfSmrg else { 177905b261ecSmrg u16 *destreg; 178035c4bbdfSmrg u8 *srcreg; 178105b261ecSmrg 178205b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 178305b261ecSmrg DECODE_PRINTF(","); 178405b261ecSmrg srcreg = DECODE_RM_BYTE_REGISTER(rl); 178505b261ecSmrg DECODE_PRINTF("\n"); 178605b261ecSmrg TRACE_AND_STEP(); 178705b261ecSmrg *destreg = *srcreg; 178805b261ecSmrg } 178905b261ecSmrg break; 179005b261ecSmrg } 179105b261ecSmrg DECODE_CLEAR_SEGOVR(); 179205b261ecSmrg END_OF_INSTR(); 179305b261ecSmrg} 179405b261ecSmrg 179505b261ecSmrg/**************************************************************************** 179605b261ecSmrgREMARKS: 179705b261ecSmrgHandles opcode 0x0f,0xb7 179805b261ecSmrg****************************************************************************/ 179935c4bbdfSmrgstatic void 180035c4bbdfSmrgx86emuOp2_movzx_word_R_RM(u8 X86EMU_UNUSED(op2)) 180105b261ecSmrg{ 180205b261ecSmrg int mod, rl, rh; 180305b261ecSmrg uint srcoffset; 180405b261ecSmrg u32 *destreg; 180505b261ecSmrg u32 srcval; 180605b261ecSmrg u16 *srcreg; 180705b261ecSmrg 180805b261ecSmrg START_OF_INSTR(); 180905b261ecSmrg DECODE_PRINTF("MOVZX\t"); 181005b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 181105b261ecSmrg switch (mod) { 181205b261ecSmrg case 0: 181305b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 181405b261ecSmrg DECODE_PRINTF(","); 181505b261ecSmrg srcoffset = decode_rm00_address(rl); 181605b261ecSmrg srcval = fetch_data_word(srcoffset); 181705b261ecSmrg DECODE_PRINTF("\n"); 181805b261ecSmrg TRACE_AND_STEP(); 181905b261ecSmrg *destreg = srcval; 182005b261ecSmrg break; 182105b261ecSmrg case 1: 182205b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 182305b261ecSmrg DECODE_PRINTF(","); 182405b261ecSmrg srcoffset = decode_rm01_address(rl); 182505b261ecSmrg srcval = fetch_data_word(srcoffset); 182605b261ecSmrg DECODE_PRINTF("\n"); 182705b261ecSmrg TRACE_AND_STEP(); 182805b261ecSmrg *destreg = srcval; 182905b261ecSmrg break; 183005b261ecSmrg case 2: 183105b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 183205b261ecSmrg DECODE_PRINTF(","); 183305b261ecSmrg srcoffset = decode_rm10_address(rl); 183405b261ecSmrg srcval = fetch_data_word(srcoffset); 183505b261ecSmrg DECODE_PRINTF("\n"); 183605b261ecSmrg TRACE_AND_STEP(); 183705b261ecSmrg *destreg = srcval; 183805b261ecSmrg break; 183935c4bbdfSmrg case 3: /* register to register */ 184005b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 184105b261ecSmrg DECODE_PRINTF(","); 184205b261ecSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 184305b261ecSmrg DECODE_PRINTF("\n"); 184405b261ecSmrg TRACE_AND_STEP(); 184505b261ecSmrg *destreg = *srcreg; 184605b261ecSmrg break; 184705b261ecSmrg } 184805b261ecSmrg DECODE_CLEAR_SEGOVR(); 184905b261ecSmrg END_OF_INSTR(); 185005b261ecSmrg} 185105b261ecSmrg 185205b261ecSmrg/**************************************************************************** 185305b261ecSmrgREMARKS: 185405b261ecSmrgHandles opcode 0x0f,0xba 185505b261ecSmrg****************************************************************************/ 185635c4bbdfSmrgstatic void 185735c4bbdfSmrgx86emuOp2_btX_I(u8 X86EMU_UNUSED(op2)) 185805b261ecSmrg{ 185905b261ecSmrg int mod, rl, rh; 186005b261ecSmrg uint srcoffset; 186105b261ecSmrg int bit; 186205b261ecSmrg 186305b261ecSmrg START_OF_INSTR(); 186405b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 186505b261ecSmrg switch (rh) { 186605b261ecSmrg case 4: 186735c4bbdfSmrg DECODE_PRINTF("BT\t"); 186835c4bbdfSmrg break; 186905b261ecSmrg case 5: 187035c4bbdfSmrg DECODE_PRINTF("BTS\t"); 187135c4bbdfSmrg break; 187205b261ecSmrg case 6: 187335c4bbdfSmrg DECODE_PRINTF("BTR\t"); 187435c4bbdfSmrg break; 187505b261ecSmrg case 7: 187635c4bbdfSmrg DECODE_PRINTF("BTC\t"); 187735c4bbdfSmrg break; 187805b261ecSmrg default: 187935c4bbdfSmrg DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n"); 188035c4bbdfSmrg TRACE_REGS(); 188135c4bbdfSmrg printk("%04x:%04x: %02X%02X ILLEGAL EXTENDED X86 OPCODE EXTENSION!\n", 188235c4bbdfSmrg M.x86.R_CS, M.x86.R_IP - 3, op2, (mod << 6) | (rh << 3) | rl); 188335c4bbdfSmrg HALT_SYS(); 188405b261ecSmrg } 188505b261ecSmrg switch (mod) { 188605b261ecSmrg case 0: 188705b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 188805b261ecSmrg u32 srcval, mask; 188905b261ecSmrg u8 shift; 189005b261ecSmrg 189105b261ecSmrg srcoffset = decode_rm00_address(rl); 189205b261ecSmrg DECODE_PRINTF(","); 189305b261ecSmrg shift = fetch_byte_imm(); 189405b261ecSmrg TRACE_AND_STEP(); 189505b261ecSmrg bit = shift & 0x1F; 189605b261ecSmrg srcval = fetch_data_long(srcoffset); 189735c4bbdfSmrg mask = (0x1 << bit); 189835c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 189935c4bbdfSmrg switch (rh) { 190035c4bbdfSmrg case 5: 190135c4bbdfSmrg store_data_long(srcoffset, srcval | mask); 190235c4bbdfSmrg break; 190335c4bbdfSmrg case 6: 190435c4bbdfSmrg store_data_long(srcoffset, srcval & ~mask); 190535c4bbdfSmrg break; 190635c4bbdfSmrg case 7: 190735c4bbdfSmrg store_data_long(srcoffset, srcval ^ mask); 190835c4bbdfSmrg break; 190935c4bbdfSmrg default: 191035c4bbdfSmrg break; 191135c4bbdfSmrg } 191235c4bbdfSmrg } 191335c4bbdfSmrg else { 191405b261ecSmrg u16 srcval, mask; 191505b261ecSmrg u8 shift; 191605b261ecSmrg 191705b261ecSmrg srcoffset = decode_rm00_address(rl); 191805b261ecSmrg DECODE_PRINTF(","); 191905b261ecSmrg shift = fetch_byte_imm(); 192005b261ecSmrg TRACE_AND_STEP(); 192105b261ecSmrg bit = shift & 0xF; 192205b261ecSmrg srcval = fetch_data_word(srcoffset); 192335c4bbdfSmrg mask = (0x1 << bit); 192435c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 192535c4bbdfSmrg switch (rh) { 192635c4bbdfSmrg case 5: 192735c4bbdfSmrg store_data_word(srcoffset, srcval | mask); 192835c4bbdfSmrg break; 192935c4bbdfSmrg case 6: 193035c4bbdfSmrg store_data_word(srcoffset, srcval & ~mask); 193135c4bbdfSmrg break; 193235c4bbdfSmrg case 7: 193335c4bbdfSmrg store_data_word(srcoffset, srcval ^ mask); 193435c4bbdfSmrg break; 193535c4bbdfSmrg default: 193635c4bbdfSmrg break; 193735c4bbdfSmrg } 193805b261ecSmrg } 193905b261ecSmrg break; 194005b261ecSmrg case 1: 194105b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 194205b261ecSmrg u32 srcval, mask; 194305b261ecSmrg u8 shift; 194405b261ecSmrg 194505b261ecSmrg srcoffset = decode_rm01_address(rl); 194605b261ecSmrg DECODE_PRINTF(","); 194705b261ecSmrg shift = fetch_byte_imm(); 194805b261ecSmrg TRACE_AND_STEP(); 194905b261ecSmrg bit = shift & 0x1F; 195005b261ecSmrg srcval = fetch_data_long(srcoffset); 195135c4bbdfSmrg mask = (0x1 << bit); 195235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 195335c4bbdfSmrg switch (rh) { 195435c4bbdfSmrg case 5: 195535c4bbdfSmrg store_data_long(srcoffset, srcval | mask); 195635c4bbdfSmrg break; 195735c4bbdfSmrg case 6: 195835c4bbdfSmrg store_data_long(srcoffset, srcval & ~mask); 195935c4bbdfSmrg break; 196035c4bbdfSmrg case 7: 196135c4bbdfSmrg store_data_long(srcoffset, srcval ^ mask); 196235c4bbdfSmrg break; 196335c4bbdfSmrg default: 196435c4bbdfSmrg break; 196535c4bbdfSmrg } 196635c4bbdfSmrg } 196735c4bbdfSmrg else { 196805b261ecSmrg u16 srcval, mask; 196905b261ecSmrg u8 shift; 197005b261ecSmrg 197105b261ecSmrg srcoffset = decode_rm01_address(rl); 197205b261ecSmrg DECODE_PRINTF(","); 197305b261ecSmrg shift = fetch_byte_imm(); 197405b261ecSmrg TRACE_AND_STEP(); 197505b261ecSmrg bit = shift & 0xF; 197605b261ecSmrg srcval = fetch_data_word(srcoffset); 197735c4bbdfSmrg mask = (0x1 << bit); 197835c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 197935c4bbdfSmrg switch (rh) { 198035c4bbdfSmrg case 5: 198135c4bbdfSmrg store_data_word(srcoffset, srcval | mask); 198235c4bbdfSmrg break; 198335c4bbdfSmrg case 6: 198435c4bbdfSmrg store_data_word(srcoffset, srcval & ~mask); 198535c4bbdfSmrg break; 198635c4bbdfSmrg case 7: 198735c4bbdfSmrg store_data_word(srcoffset, srcval ^ mask); 198835c4bbdfSmrg break; 198935c4bbdfSmrg default: 199035c4bbdfSmrg break; 199135c4bbdfSmrg } 199205b261ecSmrg } 199305b261ecSmrg break; 199405b261ecSmrg case 2: 199505b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 199605b261ecSmrg u32 srcval, mask; 199705b261ecSmrg u8 shift; 199805b261ecSmrg 199905b261ecSmrg srcoffset = decode_rm10_address(rl); 200005b261ecSmrg DECODE_PRINTF(","); 200105b261ecSmrg shift = fetch_byte_imm(); 200205b261ecSmrg TRACE_AND_STEP(); 200305b261ecSmrg bit = shift & 0x1F; 200405b261ecSmrg srcval = fetch_data_long(srcoffset); 200535c4bbdfSmrg mask = (0x1 << bit); 200635c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 200735c4bbdfSmrg switch (rh) { 200835c4bbdfSmrg case 5: 200935c4bbdfSmrg store_data_long(srcoffset, srcval | mask); 201035c4bbdfSmrg break; 201135c4bbdfSmrg case 6: 201235c4bbdfSmrg store_data_long(srcoffset, srcval & ~mask); 201335c4bbdfSmrg break; 201435c4bbdfSmrg case 7: 201535c4bbdfSmrg store_data_long(srcoffset, srcval ^ mask); 201635c4bbdfSmrg break; 201735c4bbdfSmrg default: 201835c4bbdfSmrg break; 201935c4bbdfSmrg } 202035c4bbdfSmrg } 202135c4bbdfSmrg else { 202205b261ecSmrg u16 srcval, mask; 202305b261ecSmrg u8 shift; 202405b261ecSmrg 202505b261ecSmrg srcoffset = decode_rm10_address(rl); 202605b261ecSmrg DECODE_PRINTF(","); 202705b261ecSmrg shift = fetch_byte_imm(); 202805b261ecSmrg TRACE_AND_STEP(); 202905b261ecSmrg bit = shift & 0xF; 203005b261ecSmrg srcval = fetch_data_word(srcoffset); 203135c4bbdfSmrg mask = (0x1 << bit); 203235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 203335c4bbdfSmrg switch (rh) { 203435c4bbdfSmrg case 5: 203535c4bbdfSmrg store_data_word(srcoffset, srcval | mask); 203635c4bbdfSmrg break; 203735c4bbdfSmrg case 6: 203835c4bbdfSmrg store_data_word(srcoffset, srcval & ~mask); 203935c4bbdfSmrg break; 204035c4bbdfSmrg case 7: 204135c4bbdfSmrg store_data_word(srcoffset, srcval ^ mask); 204235c4bbdfSmrg break; 204335c4bbdfSmrg default: 204435c4bbdfSmrg break; 204535c4bbdfSmrg } 204635c4bbdfSmrg } 204735c4bbdfSmrg break; 204835c4bbdfSmrg case 3: /* register to register */ 204905b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 205005b261ecSmrg u32 *srcreg; 205135c4bbdfSmrg u32 mask; 205235c4bbdfSmrg u8 shift; 205305b261ecSmrg 205405b261ecSmrg srcreg = DECODE_RM_LONG_REGISTER(rl); 205505b261ecSmrg DECODE_PRINTF(","); 205605b261ecSmrg shift = fetch_byte_imm(); 205705b261ecSmrg TRACE_AND_STEP(); 205805b261ecSmrg bit = shift & 0x1F; 205935c4bbdfSmrg mask = (0x1 << bit); 206035c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 206135c4bbdfSmrg switch (rh) { 206235c4bbdfSmrg case 5: 206335c4bbdfSmrg *srcreg |= mask; 206435c4bbdfSmrg break; 206535c4bbdfSmrg case 6: 206635c4bbdfSmrg *srcreg &= ~mask; 206735c4bbdfSmrg break; 206835c4bbdfSmrg case 7: 206935c4bbdfSmrg *srcreg ^= mask; 207035c4bbdfSmrg break; 207135c4bbdfSmrg default: 207235c4bbdfSmrg break; 207335c4bbdfSmrg } 207435c4bbdfSmrg } 207535c4bbdfSmrg else { 207605b261ecSmrg u16 *srcreg; 207735c4bbdfSmrg u16 mask; 207835c4bbdfSmrg u8 shift; 207905b261ecSmrg 208005b261ecSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 208105b261ecSmrg DECODE_PRINTF(","); 208205b261ecSmrg shift = fetch_byte_imm(); 208305b261ecSmrg TRACE_AND_STEP(); 208405b261ecSmrg bit = shift & 0xF; 208535c4bbdfSmrg mask = (0x1 << bit); 208635c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 208735c4bbdfSmrg switch (rh) { 208835c4bbdfSmrg case 5: 208935c4bbdfSmrg *srcreg |= mask; 209035c4bbdfSmrg break; 209135c4bbdfSmrg case 6: 209235c4bbdfSmrg *srcreg &= ~mask; 209335c4bbdfSmrg break; 209435c4bbdfSmrg case 7: 209535c4bbdfSmrg *srcreg ^= mask; 209635c4bbdfSmrg break; 209735c4bbdfSmrg default: 209835c4bbdfSmrg break; 209935c4bbdfSmrg } 210005b261ecSmrg } 210105b261ecSmrg break; 210205b261ecSmrg } 210305b261ecSmrg DECODE_CLEAR_SEGOVR(); 210405b261ecSmrg END_OF_INSTR(); 210505b261ecSmrg} 210605b261ecSmrg 210705b261ecSmrg/**************************************************************************** 210805b261ecSmrgREMARKS: 210905b261ecSmrgHandles opcode 0x0f,0xbb 211005b261ecSmrg****************************************************************************/ 211135c4bbdfSmrgstatic void 211235c4bbdfSmrgx86emuOp2_btc_R(u8 X86EMU_UNUSED(op2)) 211305b261ecSmrg{ 211405b261ecSmrg int mod, rl, rh; 211505b261ecSmrg uint srcoffset; 211635c4bbdfSmrg int bit, disp; 211705b261ecSmrg 211805b261ecSmrg START_OF_INSTR(); 211905b261ecSmrg DECODE_PRINTF("BTC\t"); 212005b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 212105b261ecSmrg switch (mod) { 212205b261ecSmrg case 0: 212305b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 212435c4bbdfSmrg u32 srcval, mask; 212505b261ecSmrg u32 *shiftreg; 212605b261ecSmrg 212705b261ecSmrg srcoffset = decode_rm00_address(rl); 212805b261ecSmrg DECODE_PRINTF(","); 212905b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 213005b261ecSmrg TRACE_AND_STEP(); 213105b261ecSmrg bit = *shiftreg & 0x1F; 213235c4bbdfSmrg disp = (s16) * shiftreg >> 5; 213335c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 213405b261ecSmrg mask = (0x1 << bit); 213535c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 213635c4bbdfSmrg store_data_long(srcoffset + disp, srcval ^ mask); 213735c4bbdfSmrg } 213835c4bbdfSmrg else { 213935c4bbdfSmrg u16 srcval, mask; 214005b261ecSmrg u16 *shiftreg; 214105b261ecSmrg 214205b261ecSmrg srcoffset = decode_rm00_address(rl); 214305b261ecSmrg DECODE_PRINTF(","); 214405b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 214505b261ecSmrg TRACE_AND_STEP(); 214605b261ecSmrg bit = *shiftreg & 0xF; 214735c4bbdfSmrg disp = (s16) * shiftreg >> 4; 214835c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 214935c4bbdfSmrg mask = (u16) (0x1 << bit); 215035c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 215135c4bbdfSmrg store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); 215205b261ecSmrg } 215305b261ecSmrg break; 215405b261ecSmrg case 1: 215505b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 215635c4bbdfSmrg u32 srcval, mask; 215705b261ecSmrg u32 *shiftreg; 215805b261ecSmrg 215905b261ecSmrg srcoffset = decode_rm01_address(rl); 216005b261ecSmrg DECODE_PRINTF(","); 216105b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 216205b261ecSmrg TRACE_AND_STEP(); 216305b261ecSmrg bit = *shiftreg & 0x1F; 216435c4bbdfSmrg disp = (s16) * shiftreg >> 5; 216535c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 216605b261ecSmrg mask = (0x1 << bit); 216735c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 216835c4bbdfSmrg store_data_long(srcoffset + disp, srcval ^ mask); 216935c4bbdfSmrg } 217035c4bbdfSmrg else { 217135c4bbdfSmrg u16 srcval, mask; 217205b261ecSmrg u16 *shiftreg; 217305b261ecSmrg 217405b261ecSmrg srcoffset = decode_rm01_address(rl); 217505b261ecSmrg DECODE_PRINTF(","); 217605b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 217705b261ecSmrg TRACE_AND_STEP(); 217805b261ecSmrg bit = *shiftreg & 0xF; 217935c4bbdfSmrg disp = (s16) * shiftreg >> 4; 218035c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 218135c4bbdfSmrg mask = (u16) (0x1 << bit); 218235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 218335c4bbdfSmrg store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); 218405b261ecSmrg } 218505b261ecSmrg break; 218605b261ecSmrg case 2: 218705b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 218835c4bbdfSmrg u32 srcval, mask; 218905b261ecSmrg u32 *shiftreg; 219005b261ecSmrg 219105b261ecSmrg srcoffset = decode_rm10_address(rl); 219205b261ecSmrg DECODE_PRINTF(","); 219305b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 219405b261ecSmrg TRACE_AND_STEP(); 219505b261ecSmrg bit = *shiftreg & 0x1F; 219635c4bbdfSmrg disp = (s16) * shiftreg >> 5; 219735c4bbdfSmrg srcval = fetch_data_long(srcoffset + disp); 219805b261ecSmrg mask = (0x1 << bit); 219935c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 220035c4bbdfSmrg store_data_long(srcoffset + disp, srcval ^ mask); 220135c4bbdfSmrg } 220235c4bbdfSmrg else { 220335c4bbdfSmrg u16 srcval, mask; 220405b261ecSmrg u16 *shiftreg; 220505b261ecSmrg 220605b261ecSmrg srcoffset = decode_rm10_address(rl); 220705b261ecSmrg DECODE_PRINTF(","); 220805b261ecSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 220905b261ecSmrg TRACE_AND_STEP(); 221005b261ecSmrg bit = *shiftreg & 0xF; 221135c4bbdfSmrg disp = (s16) * shiftreg >> 4; 221235c4bbdfSmrg srcval = fetch_data_word(srcoffset + disp); 221335c4bbdfSmrg mask = (u16) (0x1 << bit); 221435c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval & mask, F_CF); 221535c4bbdfSmrg store_data_word(srcoffset + disp, (u16) (srcval ^ mask)); 221605b261ecSmrg } 221705b261ecSmrg break; 221835c4bbdfSmrg case 3: /* register to register */ 221905b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 222035c4bbdfSmrg u32 *srcreg, *shiftreg; 222105b261ecSmrg u32 mask; 222205b261ecSmrg 222305b261ecSmrg srcreg = DECODE_RM_LONG_REGISTER(rl); 222405b261ecSmrg DECODE_PRINTF(","); 222505b261ecSmrg shiftreg = DECODE_RM_LONG_REGISTER(rh); 222605b261ecSmrg TRACE_AND_STEP(); 222705b261ecSmrg bit = *shiftreg & 0x1F; 222805b261ecSmrg mask = (0x1 << bit); 222935c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 223035c4bbdfSmrg *srcreg ^= mask; 223135c4bbdfSmrg } 223235c4bbdfSmrg else { 223335c4bbdfSmrg u16 *srcreg, *shiftreg; 223435c4bbdfSmrg u16 mask; 223535c4bbdfSmrg 223635c4bbdfSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 223735c4bbdfSmrg DECODE_PRINTF(","); 223835c4bbdfSmrg shiftreg = DECODE_RM_WORD_REGISTER(rh); 223935c4bbdfSmrg TRACE_AND_STEP(); 224035c4bbdfSmrg bit = *shiftreg & 0xF; 224135c4bbdfSmrg mask = (u16) (0x1 << bit); 224235c4bbdfSmrg CONDITIONAL_SET_FLAG(*srcreg & mask, F_CF); 224305b261ecSmrg *srcreg ^= mask; 224405b261ecSmrg } 224505b261ecSmrg break; 224605b261ecSmrg } 224705b261ecSmrg DECODE_CLEAR_SEGOVR(); 224805b261ecSmrg END_OF_INSTR(); 224905b261ecSmrg} 225005b261ecSmrg 225105b261ecSmrg/**************************************************************************** 225205b261ecSmrgREMARKS: 225305b261ecSmrgHandles opcode 0x0f,0xbc 225405b261ecSmrg****************************************************************************/ 225535c4bbdfSmrgstatic void 225635c4bbdfSmrgx86emuOp2_bsf(u8 X86EMU_UNUSED(op2)) 225705b261ecSmrg{ 225805b261ecSmrg int mod, rl, rh; 225905b261ecSmrg uint srcoffset; 226005b261ecSmrg 226105b261ecSmrg START_OF_INSTR(); 226205b261ecSmrg DECODE_PRINTF("BSF\t"); 226305b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 226435c4bbdfSmrg switch (mod) { 226505b261ecSmrg case 0: 226635c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 226735c4bbdfSmrg u32 srcval, *dstreg; 226835c4bbdfSmrg 226935c4bbdfSmrg srcoffset = decode_rm00_address(rl); 227035c4bbdfSmrg DECODE_PRINTF(","); 227135c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 227235c4bbdfSmrg TRACE_AND_STEP(); 227335c4bbdfSmrg srcval = fetch_data_long(srcoffset); 227435c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 227535c4bbdfSmrg for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 227635c4bbdfSmrg if ((srcval >> *dstreg) & 1) 227735c4bbdfSmrg break; 227835c4bbdfSmrg } 227935c4bbdfSmrg else { 228035c4bbdfSmrg u16 srcval, *dstreg; 228135c4bbdfSmrg 228235c4bbdfSmrg srcoffset = decode_rm00_address(rl); 228335c4bbdfSmrg DECODE_PRINTF(","); 228435c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 228535c4bbdfSmrg TRACE_AND_STEP(); 228635c4bbdfSmrg srcval = fetch_data_word(srcoffset); 228735c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 228835c4bbdfSmrg for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 228935c4bbdfSmrg if ((srcval >> *dstreg) & 1) 229035c4bbdfSmrg break; 229135c4bbdfSmrg } 229235c4bbdfSmrg break; 229305b261ecSmrg case 1: 229435c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 229535c4bbdfSmrg u32 srcval, *dstreg; 229635c4bbdfSmrg 229735c4bbdfSmrg srcoffset = decode_rm01_address(rl); 229835c4bbdfSmrg DECODE_PRINTF(","); 229935c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 230035c4bbdfSmrg TRACE_AND_STEP(); 230135c4bbdfSmrg srcval = fetch_data_long(srcoffset); 230235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 230335c4bbdfSmrg for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 230435c4bbdfSmrg if ((srcval >> *dstreg) & 1) 230535c4bbdfSmrg break; 230635c4bbdfSmrg } 230735c4bbdfSmrg else { 230835c4bbdfSmrg u16 srcval, *dstreg; 230935c4bbdfSmrg 231035c4bbdfSmrg srcoffset = decode_rm01_address(rl); 231135c4bbdfSmrg DECODE_PRINTF(","); 231235c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 231335c4bbdfSmrg TRACE_AND_STEP(); 231435c4bbdfSmrg srcval = fetch_data_word(srcoffset); 231535c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 231635c4bbdfSmrg for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 231735c4bbdfSmrg if ((srcval >> *dstreg) & 1) 231835c4bbdfSmrg break; 231935c4bbdfSmrg } 232035c4bbdfSmrg break; 232105b261ecSmrg case 2: 232235c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 232335c4bbdfSmrg u32 srcval, *dstreg; 232435c4bbdfSmrg 232535c4bbdfSmrg srcoffset = decode_rm10_address(rl); 232635c4bbdfSmrg DECODE_PRINTF(","); 232735c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 232835c4bbdfSmrg TRACE_AND_STEP(); 232935c4bbdfSmrg srcval = fetch_data_long(srcoffset); 233035c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 233135c4bbdfSmrg for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 233235c4bbdfSmrg if ((srcval >> *dstreg) & 1) 233335c4bbdfSmrg break; 233435c4bbdfSmrg } 233535c4bbdfSmrg else { 233635c4bbdfSmrg u16 srcval, *dstreg; 233735c4bbdfSmrg 233835c4bbdfSmrg srcoffset = decode_rm10_address(rl); 233935c4bbdfSmrg DECODE_PRINTF(","); 234035c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 234135c4bbdfSmrg TRACE_AND_STEP(); 234235c4bbdfSmrg srcval = fetch_data_word(srcoffset); 234335c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 234435c4bbdfSmrg for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 234535c4bbdfSmrg if ((srcval >> *dstreg) & 1) 234635c4bbdfSmrg break; 234735c4bbdfSmrg } 234835c4bbdfSmrg break; 234935c4bbdfSmrg case 3: /* register to register */ 235035c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 235135c4bbdfSmrg u32 srcval, *dstreg; 235235c4bbdfSmrg 235335c4bbdfSmrg srcval = *DECODE_RM_LONG_REGISTER(rl); 235435c4bbdfSmrg DECODE_PRINTF(","); 235535c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 235635c4bbdfSmrg TRACE_AND_STEP(); 235735c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 235835c4bbdfSmrg for (*dstreg = 0; *dstreg < 32; (*dstreg)++) 235935c4bbdfSmrg if ((srcval >> *dstreg) & 1) 236035c4bbdfSmrg break; 236135c4bbdfSmrg } 236235c4bbdfSmrg else { 236335c4bbdfSmrg u16 srcval, *dstreg; 236435c4bbdfSmrg 236535c4bbdfSmrg srcval = *DECODE_RM_WORD_REGISTER(rl); 236635c4bbdfSmrg DECODE_PRINTF(","); 236735c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 236835c4bbdfSmrg TRACE_AND_STEP(); 236935c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 237035c4bbdfSmrg for (*dstreg = 0; *dstreg < 16; (*dstreg)++) 237135c4bbdfSmrg if ((srcval >> *dstreg) & 1) 237235c4bbdfSmrg break; 237335c4bbdfSmrg } 237435c4bbdfSmrg break; 237505b261ecSmrg } 237605b261ecSmrg DECODE_CLEAR_SEGOVR(); 237705b261ecSmrg END_OF_INSTR(); 237805b261ecSmrg} 237905b261ecSmrg 238005b261ecSmrg/**************************************************************************** 238105b261ecSmrgREMARKS: 238205b261ecSmrgHandles opcode 0x0f,0xbd 238305b261ecSmrg****************************************************************************/ 238435c4bbdfSmrgstatic void 238535c4bbdfSmrgx86emuOp2_bsr(u8 X86EMU_UNUSED(op2)) 238605b261ecSmrg{ 238705b261ecSmrg int mod, rl, rh; 238805b261ecSmrg uint srcoffset; 238905b261ecSmrg 239005b261ecSmrg START_OF_INSTR(); 239105b261ecSmrg DECODE_PRINTF("BSR\t"); 239205b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 239335c4bbdfSmrg switch (mod) { 239405b261ecSmrg case 0: 239535c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 239635c4bbdfSmrg u32 srcval, *dstreg; 239735c4bbdfSmrg 239835c4bbdfSmrg srcoffset = decode_rm00_address(rl); 239935c4bbdfSmrg DECODE_PRINTF(","); 240035c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 240135c4bbdfSmrg TRACE_AND_STEP(); 240235c4bbdfSmrg srcval = fetch_data_long(srcoffset); 240335c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 240435c4bbdfSmrg for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 240535c4bbdfSmrg if ((srcval >> *dstreg) & 1) 240635c4bbdfSmrg break; 240735c4bbdfSmrg } 240835c4bbdfSmrg else { 240935c4bbdfSmrg u16 srcval, *dstreg; 241035c4bbdfSmrg 241135c4bbdfSmrg srcoffset = decode_rm00_address(rl); 241235c4bbdfSmrg DECODE_PRINTF(","); 241335c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 241435c4bbdfSmrg TRACE_AND_STEP(); 241535c4bbdfSmrg srcval = fetch_data_word(srcoffset); 241635c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 241735c4bbdfSmrg for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 241835c4bbdfSmrg if ((srcval >> *dstreg) & 1) 241935c4bbdfSmrg break; 242035c4bbdfSmrg } 242135c4bbdfSmrg break; 242205b261ecSmrg case 1: 242335c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 242435c4bbdfSmrg u32 srcval, *dstreg; 242535c4bbdfSmrg 242635c4bbdfSmrg srcoffset = decode_rm01_address(rl); 242735c4bbdfSmrg DECODE_PRINTF(","); 242835c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 242935c4bbdfSmrg TRACE_AND_STEP(); 243035c4bbdfSmrg srcval = fetch_data_long(srcoffset); 243135c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 243235c4bbdfSmrg for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 243335c4bbdfSmrg if ((srcval >> *dstreg) & 1) 243435c4bbdfSmrg break; 243535c4bbdfSmrg } 243635c4bbdfSmrg else { 243735c4bbdfSmrg u16 srcval, *dstreg; 243835c4bbdfSmrg 243935c4bbdfSmrg srcoffset = decode_rm01_address(rl); 244035c4bbdfSmrg DECODE_PRINTF(","); 244135c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 244235c4bbdfSmrg TRACE_AND_STEP(); 244335c4bbdfSmrg srcval = fetch_data_word(srcoffset); 244435c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 244535c4bbdfSmrg for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 244635c4bbdfSmrg if ((srcval >> *dstreg) & 1) 244735c4bbdfSmrg break; 244835c4bbdfSmrg } 244935c4bbdfSmrg break; 245005b261ecSmrg case 2: 245135c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 245235c4bbdfSmrg u32 srcval, *dstreg; 245335c4bbdfSmrg 245435c4bbdfSmrg srcoffset = decode_rm10_address(rl); 245535c4bbdfSmrg DECODE_PRINTF(","); 245635c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 245735c4bbdfSmrg TRACE_AND_STEP(); 245835c4bbdfSmrg srcval = fetch_data_long(srcoffset); 245935c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 246035c4bbdfSmrg for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 246135c4bbdfSmrg if ((srcval >> *dstreg) & 1) 246235c4bbdfSmrg break; 246335c4bbdfSmrg } 246435c4bbdfSmrg else { 246535c4bbdfSmrg u16 srcval, *dstreg; 246635c4bbdfSmrg 246735c4bbdfSmrg srcoffset = decode_rm10_address(rl); 246835c4bbdfSmrg DECODE_PRINTF(","); 246935c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 247035c4bbdfSmrg TRACE_AND_STEP(); 247135c4bbdfSmrg srcval = fetch_data_word(srcoffset); 247235c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 247335c4bbdfSmrg for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 247435c4bbdfSmrg if ((srcval >> *dstreg) & 1) 247535c4bbdfSmrg break; 247635c4bbdfSmrg } 247735c4bbdfSmrg break; 247835c4bbdfSmrg case 3: /* register to register */ 247935c4bbdfSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 248035c4bbdfSmrg u32 srcval, *dstreg; 248135c4bbdfSmrg 248235c4bbdfSmrg srcval = *DECODE_RM_LONG_REGISTER(rl); 248335c4bbdfSmrg DECODE_PRINTF(","); 248435c4bbdfSmrg dstreg = DECODE_RM_LONG_REGISTER(rh); 248535c4bbdfSmrg TRACE_AND_STEP(); 248635c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 248735c4bbdfSmrg for (*dstreg = 31; *dstreg > 0; (*dstreg)--) 248835c4bbdfSmrg if ((srcval >> *dstreg) & 1) 248935c4bbdfSmrg break; 249035c4bbdfSmrg } 249135c4bbdfSmrg else { 249235c4bbdfSmrg u16 srcval, *dstreg; 249335c4bbdfSmrg 249435c4bbdfSmrg srcval = *DECODE_RM_WORD_REGISTER(rl); 249535c4bbdfSmrg DECODE_PRINTF(","); 249635c4bbdfSmrg dstreg = DECODE_RM_WORD_REGISTER(rh); 249735c4bbdfSmrg TRACE_AND_STEP(); 249835c4bbdfSmrg CONDITIONAL_SET_FLAG(srcval == 0, F_ZF); 249935c4bbdfSmrg for (*dstreg = 15; *dstreg > 0; (*dstreg)--) 250035c4bbdfSmrg if ((srcval >> *dstreg) & 1) 250135c4bbdfSmrg break; 250235c4bbdfSmrg } 250335c4bbdfSmrg break; 250405b261ecSmrg } 250505b261ecSmrg DECODE_CLEAR_SEGOVR(); 250605b261ecSmrg END_OF_INSTR(); 250705b261ecSmrg} 250805b261ecSmrg 250905b261ecSmrg/**************************************************************************** 251005b261ecSmrgREMARKS: 251105b261ecSmrgHandles opcode 0x0f,0xbe 251205b261ecSmrg****************************************************************************/ 251335c4bbdfSmrgstatic void 251435c4bbdfSmrgx86emuOp2_movsx_byte_R_RM(u8 X86EMU_UNUSED(op2)) 251505b261ecSmrg{ 251605b261ecSmrg int mod, rl, rh; 251705b261ecSmrg uint srcoffset; 251805b261ecSmrg 251905b261ecSmrg START_OF_INSTR(); 252005b261ecSmrg DECODE_PRINTF("MOVSX\t"); 252105b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 252205b261ecSmrg switch (mod) { 252305b261ecSmrg case 0: 252405b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 252505b261ecSmrg u32 *destreg; 252605b261ecSmrg u32 srcval; 252705b261ecSmrg 252805b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 252905b261ecSmrg DECODE_PRINTF(","); 253005b261ecSmrg srcoffset = decode_rm00_address(rl); 253135c4bbdfSmrg srcval = (s32) ((s8) fetch_data_byte(srcoffset)); 253205b261ecSmrg DECODE_PRINTF("\n"); 253305b261ecSmrg TRACE_AND_STEP(); 253405b261ecSmrg *destreg = srcval; 253535c4bbdfSmrg } 253635c4bbdfSmrg else { 253705b261ecSmrg u16 *destreg; 253805b261ecSmrg u16 srcval; 253905b261ecSmrg 254005b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 254105b261ecSmrg DECODE_PRINTF(","); 254205b261ecSmrg srcoffset = decode_rm00_address(rl); 254335c4bbdfSmrg srcval = (s16) ((s8) fetch_data_byte(srcoffset)); 254405b261ecSmrg DECODE_PRINTF("\n"); 254505b261ecSmrg TRACE_AND_STEP(); 254605b261ecSmrg *destreg = srcval; 254705b261ecSmrg } 254805b261ecSmrg break; 254905b261ecSmrg case 1: 255005b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 255105b261ecSmrg u32 *destreg; 255205b261ecSmrg u32 srcval; 255305b261ecSmrg 255405b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 255505b261ecSmrg DECODE_PRINTF(","); 255605b261ecSmrg srcoffset = decode_rm01_address(rl); 255735c4bbdfSmrg srcval = (s32) ((s8) fetch_data_byte(srcoffset)); 255805b261ecSmrg DECODE_PRINTF("\n"); 255905b261ecSmrg TRACE_AND_STEP(); 256005b261ecSmrg *destreg = srcval; 256135c4bbdfSmrg } 256235c4bbdfSmrg else { 256305b261ecSmrg u16 *destreg; 256405b261ecSmrg u16 srcval; 256505b261ecSmrg 256605b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 256705b261ecSmrg DECODE_PRINTF(","); 256805b261ecSmrg srcoffset = decode_rm01_address(rl); 256935c4bbdfSmrg srcval = (s16) ((s8) fetch_data_byte(srcoffset)); 257005b261ecSmrg DECODE_PRINTF("\n"); 257105b261ecSmrg TRACE_AND_STEP(); 257205b261ecSmrg *destreg = srcval; 257305b261ecSmrg } 257405b261ecSmrg break; 257505b261ecSmrg case 2: 257605b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 257705b261ecSmrg u32 *destreg; 257805b261ecSmrg u32 srcval; 257905b261ecSmrg 258005b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 258105b261ecSmrg DECODE_PRINTF(","); 258205b261ecSmrg srcoffset = decode_rm10_address(rl); 258335c4bbdfSmrg srcval = (s32) ((s8) fetch_data_byte(srcoffset)); 258405b261ecSmrg DECODE_PRINTF("\n"); 258505b261ecSmrg TRACE_AND_STEP(); 258605b261ecSmrg *destreg = srcval; 258735c4bbdfSmrg } 258835c4bbdfSmrg else { 258905b261ecSmrg u16 *destreg; 259005b261ecSmrg u16 srcval; 259105b261ecSmrg 259205b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 259305b261ecSmrg DECODE_PRINTF(","); 259405b261ecSmrg srcoffset = decode_rm10_address(rl); 259535c4bbdfSmrg srcval = (s16) ((s8) fetch_data_byte(srcoffset)); 259605b261ecSmrg DECODE_PRINTF("\n"); 259705b261ecSmrg TRACE_AND_STEP(); 259805b261ecSmrg *destreg = srcval; 259905b261ecSmrg } 260005b261ecSmrg break; 260135c4bbdfSmrg case 3: /* register to register */ 260205b261ecSmrg if (M.x86.mode & SYSMODE_PREFIX_DATA) { 260305b261ecSmrg u32 *destreg; 260435c4bbdfSmrg u8 *srcreg; 260505b261ecSmrg 260605b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 260705b261ecSmrg DECODE_PRINTF(","); 260805b261ecSmrg srcreg = DECODE_RM_BYTE_REGISTER(rl); 260905b261ecSmrg DECODE_PRINTF("\n"); 261005b261ecSmrg TRACE_AND_STEP(); 261135c4bbdfSmrg *destreg = (s32) ((s8) * srcreg); 261235c4bbdfSmrg } 261335c4bbdfSmrg else { 261405b261ecSmrg u16 *destreg; 261535c4bbdfSmrg u8 *srcreg; 261605b261ecSmrg 261705b261ecSmrg destreg = DECODE_RM_WORD_REGISTER(rh); 261805b261ecSmrg DECODE_PRINTF(","); 261905b261ecSmrg srcreg = DECODE_RM_BYTE_REGISTER(rl); 262005b261ecSmrg DECODE_PRINTF("\n"); 262105b261ecSmrg TRACE_AND_STEP(); 262235c4bbdfSmrg *destreg = (s16) ((s8) * srcreg); 262305b261ecSmrg } 262405b261ecSmrg break; 262505b261ecSmrg } 262605b261ecSmrg DECODE_CLEAR_SEGOVR(); 262705b261ecSmrg END_OF_INSTR(); 262805b261ecSmrg} 262905b261ecSmrg 263005b261ecSmrg/**************************************************************************** 263105b261ecSmrgREMARKS: 263205b261ecSmrgHandles opcode 0x0f,0xbf 263305b261ecSmrg****************************************************************************/ 263435c4bbdfSmrgstatic void 263535c4bbdfSmrgx86emuOp2_movsx_word_R_RM(u8 X86EMU_UNUSED(op2)) 263605b261ecSmrg{ 263705b261ecSmrg int mod, rl, rh; 263805b261ecSmrg uint srcoffset; 263905b261ecSmrg u32 *destreg; 264005b261ecSmrg u32 srcval; 264105b261ecSmrg u16 *srcreg; 264205b261ecSmrg 264305b261ecSmrg START_OF_INSTR(); 264405b261ecSmrg DECODE_PRINTF("MOVSX\t"); 264505b261ecSmrg FETCH_DECODE_MODRM(mod, rh, rl); 264605b261ecSmrg switch (mod) { 264705b261ecSmrg case 0: 264805b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 264905b261ecSmrg DECODE_PRINTF(","); 265005b261ecSmrg srcoffset = decode_rm00_address(rl); 265135c4bbdfSmrg srcval = (s32) ((s16) fetch_data_word(srcoffset)); 265205b261ecSmrg DECODE_PRINTF("\n"); 265305b261ecSmrg TRACE_AND_STEP(); 265405b261ecSmrg *destreg = srcval; 265505b261ecSmrg break; 265605b261ecSmrg case 1: 265705b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 265805b261ecSmrg DECODE_PRINTF(","); 265905b261ecSmrg srcoffset = decode_rm01_address(rl); 266035c4bbdfSmrg srcval = (s32) ((s16) fetch_data_word(srcoffset)); 266105b261ecSmrg DECODE_PRINTF("\n"); 266205b261ecSmrg TRACE_AND_STEP(); 266305b261ecSmrg *destreg = srcval; 266405b261ecSmrg break; 266505b261ecSmrg case 2: 266605b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 266705b261ecSmrg DECODE_PRINTF(","); 266805b261ecSmrg srcoffset = decode_rm10_address(rl); 266935c4bbdfSmrg srcval = (s32) ((s16) fetch_data_word(srcoffset)); 267005b261ecSmrg DECODE_PRINTF("\n"); 267105b261ecSmrg TRACE_AND_STEP(); 267205b261ecSmrg *destreg = srcval; 267305b261ecSmrg break; 267435c4bbdfSmrg case 3: /* register to register */ 267505b261ecSmrg destreg = DECODE_RM_LONG_REGISTER(rh); 267605b261ecSmrg DECODE_PRINTF(","); 267705b261ecSmrg srcreg = DECODE_RM_WORD_REGISTER(rl); 267805b261ecSmrg DECODE_PRINTF("\n"); 267905b261ecSmrg TRACE_AND_STEP(); 268035c4bbdfSmrg *destreg = (s32) ((s16) * srcreg); 268105b261ecSmrg break; 268205b261ecSmrg } 268305b261ecSmrg DECODE_CLEAR_SEGOVR(); 268405b261ecSmrg END_OF_INSTR(); 268505b261ecSmrg} 268605b261ecSmrg 26874642e01fSmrg/* Handles opcodes 0xc8-0xcf */ 268835c4bbdfSmrgstatic void 268935c4bbdfSmrgx86emuOp2_bswap(u8 X86EMU_UNUSED(op2)) 26904642e01fSmrg{ 26914642e01fSmrg START_OF_INSTR(); 26924642e01fSmrg DECODE_PRINTF("BSWAP\n"); 26934642e01fSmrg TRACE_AND_STEP(); 26944642e01fSmrg 26954642e01fSmrg switch (op2) { 269635c4bbdfSmrg case 0xc8: 269735c4bbdfSmrg M.x86.R_EAX = bswap_32(M.x86.R_EAX); 269835c4bbdfSmrg break; 269935c4bbdfSmrg case 0xc9: 270035c4bbdfSmrg M.x86.R_ECX = bswap_32(M.x86.R_ECX); 270135c4bbdfSmrg break; 270235c4bbdfSmrg case 0xca: 270335c4bbdfSmrg M.x86.R_EDX = bswap_32(M.x86.R_EDX); 270435c4bbdfSmrg break; 270535c4bbdfSmrg case 0xcb: 270635c4bbdfSmrg M.x86.R_EBX = bswap_32(M.x86.R_EBX); 270735c4bbdfSmrg break; 270835c4bbdfSmrg case 0xcc: 270935c4bbdfSmrg M.x86.R_ESP = bswap_32(M.x86.R_ESP); 271035c4bbdfSmrg break; 271135c4bbdfSmrg case 0xcd: 271235c4bbdfSmrg M.x86.R_EBP = bswap_32(M.x86.R_EBP); 271335c4bbdfSmrg break; 271435c4bbdfSmrg case 0xce: 271535c4bbdfSmrg M.x86.R_ESI = bswap_32(M.x86.R_ESI); 271635c4bbdfSmrg break; 271735c4bbdfSmrg case 0xcf: 271835c4bbdfSmrg M.x86.R_EDI = bswap_32(M.x86.R_EDI); 271935c4bbdfSmrg break; 272035c4bbdfSmrg default: 272135c4bbdfSmrg /* can't happen */ 272235c4bbdfSmrg break; 27234642e01fSmrg } 27244642e01fSmrg 27254642e01fSmrg DECODE_CLEAR_SEGOVR(); 27264642e01fSmrg END_OF_INSTR(); 27274642e01fSmrg} 27284642e01fSmrg 272905b261ecSmrg/*************************************************************************** 273005b261ecSmrg * Double byte operation code table: 273105b261ecSmrg **************************************************************************/ 273235c4bbdfSmrgvoid (*x86emu_optab2[256]) (u8) = { 273335c4bbdfSmrg /* 0x00 */ x86emuOp2_illegal_op, 273435c4bbdfSmrg /* Group F (ring 0 PM) */ 273535c4bbdfSmrg /* 0x01 */ x86emuOp2_illegal_op, 273635c4bbdfSmrg /* Group G (ring 0 PM) */ 273735c4bbdfSmrg /* 0x02 */ x86emuOp2_illegal_op, 273835c4bbdfSmrg /* lar (ring 0 PM) */ 273935c4bbdfSmrg /* 0x03 */ x86emuOp2_illegal_op, 274035c4bbdfSmrg /* lsl (ring 0 PM) */ 274105b261ecSmrg/* 0x04 */ x86emuOp2_illegal_op, 274235c4bbdfSmrg /* 0x05 */ x86emuOp2_illegal_op, 274335c4bbdfSmrg /* loadall (undocumented) */ 274435c4bbdfSmrg /* 0x06 */ x86emuOp2_illegal_op, 274535c4bbdfSmrg /* clts (ring 0 PM) */ 274635c4bbdfSmrg /* 0x07 */ x86emuOp2_illegal_op, 274735c4bbdfSmrg /* loadall (undocumented) */ 274835c4bbdfSmrg /* 0x08 */ x86emuOp2_illegal_op, 274935c4bbdfSmrg /* invd (ring 0 PM) */ 275035c4bbdfSmrg /* 0x09 */ x86emuOp2_illegal_op, 275135c4bbdfSmrg /* wbinvd (ring 0 PM) */ 275205b261ecSmrg/* 0x0a */ x86emuOp2_illegal_op, 275305b261ecSmrg/* 0x0b */ x86emuOp2_illegal_op, 275405b261ecSmrg/* 0x0c */ x86emuOp2_illegal_op, 275505b261ecSmrg/* 0x0d */ x86emuOp2_illegal_op, 275605b261ecSmrg/* 0x0e */ x86emuOp2_illegal_op, 275705b261ecSmrg/* 0x0f */ x86emuOp2_illegal_op, 275805b261ecSmrg/* 0x10 */ x86emuOp2_illegal_op, 275905b261ecSmrg/* 0x11 */ x86emuOp2_illegal_op, 276005b261ecSmrg/* 0x12 */ x86emuOp2_illegal_op, 276105b261ecSmrg/* 0x13 */ x86emuOp2_illegal_op, 276205b261ecSmrg/* 0x14 */ x86emuOp2_illegal_op, 276305b261ecSmrg/* 0x15 */ x86emuOp2_illegal_op, 276405b261ecSmrg/* 0x16 */ x86emuOp2_illegal_op, 276505b261ecSmrg/* 0x17 */ x86emuOp2_illegal_op, 276605b261ecSmrg/* 0x18 */ x86emuOp2_illegal_op, 276705b261ecSmrg/* 0x19 */ x86emuOp2_illegal_op, 276805b261ecSmrg/* 0x1a */ x86emuOp2_illegal_op, 276905b261ecSmrg/* 0x1b */ x86emuOp2_illegal_op, 277005b261ecSmrg/* 0x1c */ x86emuOp2_illegal_op, 277105b261ecSmrg/* 0x1d */ x86emuOp2_illegal_op, 277205b261ecSmrg/* 0x1e */ x86emuOp2_illegal_op, 277305b261ecSmrg/* 0x1f */ x86emuOp2_illegal_op, 277435c4bbdfSmrg /* 0x20 */ x86emuOp2_illegal_op, 277535c4bbdfSmrg /* mov reg32,creg (ring 0 PM) */ 277635c4bbdfSmrg /* 0x21 */ x86emuOp2_illegal_op, 277735c4bbdfSmrg /* mov reg32,dreg (ring 0 PM) */ 277835c4bbdfSmrg /* 0x22 */ x86emuOp2_illegal_op, 277935c4bbdfSmrg /* mov creg,reg32 (ring 0 PM) */ 278035c4bbdfSmrg /* 0x23 */ x86emuOp2_illegal_op, 278135c4bbdfSmrg /* mov dreg,reg32 (ring 0 PM) */ 278235c4bbdfSmrg /* 0x24 */ x86emuOp2_illegal_op, 278335c4bbdfSmrg /* mov reg32,treg (ring 0 PM) */ 278405b261ecSmrg/* 0x25 */ x86emuOp2_illegal_op, 278535c4bbdfSmrg /* 0x26 */ x86emuOp2_illegal_op, 278635c4bbdfSmrg /* mov treg,reg32 (ring 0 PM) */ 278705b261ecSmrg/* 0x27 */ x86emuOp2_illegal_op, 278805b261ecSmrg/* 0x28 */ x86emuOp2_illegal_op, 278905b261ecSmrg/* 0x29 */ x86emuOp2_illegal_op, 279005b261ecSmrg/* 0x2a */ x86emuOp2_illegal_op, 279105b261ecSmrg/* 0x2b */ x86emuOp2_illegal_op, 279205b261ecSmrg/* 0x2c */ x86emuOp2_illegal_op, 279305b261ecSmrg/* 0x2d */ x86emuOp2_illegal_op, 279405b261ecSmrg/* 0x2e */ x86emuOp2_illegal_op, 279505b261ecSmrg/* 0x2f */ x86emuOp2_illegal_op, 279605b261ecSmrg/* 0x30 */ x86emuOp2_illegal_op, 279705b261ecSmrg/* 0x31 */ x86emuOp2_rdtsc, 279805b261ecSmrg/* 0x32 */ x86emuOp2_illegal_op, 279905b261ecSmrg/* 0x33 */ x86emuOp2_illegal_op, 280005b261ecSmrg/* 0x34 */ x86emuOp2_illegal_op, 280105b261ecSmrg/* 0x35 */ x86emuOp2_illegal_op, 280205b261ecSmrg/* 0x36 */ x86emuOp2_illegal_op, 280305b261ecSmrg/* 0x37 */ x86emuOp2_illegal_op, 280405b261ecSmrg/* 0x38 */ x86emuOp2_illegal_op, 280505b261ecSmrg/* 0x39 */ x86emuOp2_illegal_op, 280605b261ecSmrg/* 0x3a */ x86emuOp2_illegal_op, 280705b261ecSmrg/* 0x3b */ x86emuOp2_illegal_op, 280805b261ecSmrg/* 0x3c */ x86emuOp2_illegal_op, 280905b261ecSmrg/* 0x3d */ x86emuOp2_illegal_op, 281005b261ecSmrg/* 0x3e */ x86emuOp2_illegal_op, 281105b261ecSmrg/* 0x3f */ x86emuOp2_illegal_op, 281205b261ecSmrg/* 0x40 */ x86emuOp2_illegal_op, 281305b261ecSmrg/* 0x41 */ x86emuOp2_illegal_op, 281405b261ecSmrg/* 0x42 */ x86emuOp2_illegal_op, 281505b261ecSmrg/* 0x43 */ x86emuOp2_illegal_op, 281605b261ecSmrg/* 0x44 */ x86emuOp2_illegal_op, 281705b261ecSmrg/* 0x45 */ x86emuOp2_illegal_op, 281805b261ecSmrg/* 0x46 */ x86emuOp2_illegal_op, 281905b261ecSmrg/* 0x47 */ x86emuOp2_illegal_op, 282005b261ecSmrg/* 0x48 */ x86emuOp2_illegal_op, 282105b261ecSmrg/* 0x49 */ x86emuOp2_illegal_op, 282205b261ecSmrg/* 0x4a */ x86emuOp2_illegal_op, 282305b261ecSmrg/* 0x4b */ x86emuOp2_illegal_op, 282405b261ecSmrg/* 0x4c */ x86emuOp2_illegal_op, 282505b261ecSmrg/* 0x4d */ x86emuOp2_illegal_op, 282605b261ecSmrg/* 0x4e */ x86emuOp2_illegal_op, 282705b261ecSmrg/* 0x4f */ x86emuOp2_illegal_op, 282805b261ecSmrg/* 0x50 */ x86emuOp2_illegal_op, 282905b261ecSmrg/* 0x51 */ x86emuOp2_illegal_op, 283005b261ecSmrg/* 0x52 */ x86emuOp2_illegal_op, 283105b261ecSmrg/* 0x53 */ x86emuOp2_illegal_op, 283205b261ecSmrg/* 0x54 */ x86emuOp2_illegal_op, 283305b261ecSmrg/* 0x55 */ x86emuOp2_illegal_op, 283405b261ecSmrg/* 0x56 */ x86emuOp2_illegal_op, 283505b261ecSmrg/* 0x57 */ x86emuOp2_illegal_op, 283605b261ecSmrg/* 0x58 */ x86emuOp2_illegal_op, 283705b261ecSmrg/* 0x59 */ x86emuOp2_illegal_op, 283805b261ecSmrg/* 0x5a */ x86emuOp2_illegal_op, 283905b261ecSmrg/* 0x5b */ x86emuOp2_illegal_op, 284005b261ecSmrg/* 0x5c */ x86emuOp2_illegal_op, 284105b261ecSmrg/* 0x5d */ x86emuOp2_illegal_op, 284205b261ecSmrg/* 0x5e */ x86emuOp2_illegal_op, 284305b261ecSmrg/* 0x5f */ x86emuOp2_illegal_op, 284405b261ecSmrg/* 0x60 */ x86emuOp2_illegal_op, 284505b261ecSmrg/* 0x61 */ x86emuOp2_illegal_op, 284605b261ecSmrg/* 0x62 */ x86emuOp2_illegal_op, 284705b261ecSmrg/* 0x63 */ x86emuOp2_illegal_op, 284805b261ecSmrg/* 0x64 */ x86emuOp2_illegal_op, 284905b261ecSmrg/* 0x65 */ x86emuOp2_illegal_op, 285005b261ecSmrg/* 0x66 */ x86emuOp2_illegal_op, 285105b261ecSmrg/* 0x67 */ x86emuOp2_illegal_op, 285205b261ecSmrg/* 0x68 */ x86emuOp2_illegal_op, 285305b261ecSmrg/* 0x69 */ x86emuOp2_illegal_op, 285405b261ecSmrg/* 0x6a */ x86emuOp2_illegal_op, 285505b261ecSmrg/* 0x6b */ x86emuOp2_illegal_op, 285605b261ecSmrg/* 0x6c */ x86emuOp2_illegal_op, 285705b261ecSmrg/* 0x6d */ x86emuOp2_illegal_op, 285805b261ecSmrg/* 0x6e */ x86emuOp2_illegal_op, 285905b261ecSmrg/* 0x6f */ x86emuOp2_illegal_op, 286005b261ecSmrg/* 0x70 */ x86emuOp2_illegal_op, 286105b261ecSmrg/* 0x71 */ x86emuOp2_illegal_op, 286205b261ecSmrg/* 0x72 */ x86emuOp2_illegal_op, 286305b261ecSmrg/* 0x73 */ x86emuOp2_illegal_op, 286405b261ecSmrg/* 0x74 */ x86emuOp2_illegal_op, 286505b261ecSmrg/* 0x75 */ x86emuOp2_illegal_op, 286605b261ecSmrg/* 0x76 */ x86emuOp2_illegal_op, 286705b261ecSmrg/* 0x77 */ x86emuOp2_illegal_op, 286805b261ecSmrg/* 0x78 */ x86emuOp2_illegal_op, 286905b261ecSmrg/* 0x79 */ x86emuOp2_illegal_op, 287005b261ecSmrg/* 0x7a */ x86emuOp2_illegal_op, 287105b261ecSmrg/* 0x7b */ x86emuOp2_illegal_op, 287205b261ecSmrg/* 0x7c */ x86emuOp2_illegal_op, 287305b261ecSmrg/* 0x7d */ x86emuOp2_illegal_op, 287405b261ecSmrg/* 0x7e */ x86emuOp2_illegal_op, 287505b261ecSmrg/* 0x7f */ x86emuOp2_illegal_op, 287605b261ecSmrg/* 0x80 */ x86emuOp2_long_jump, 287705b261ecSmrg/* 0x81 */ x86emuOp2_long_jump, 287805b261ecSmrg/* 0x82 */ x86emuOp2_long_jump, 287905b261ecSmrg/* 0x83 */ x86emuOp2_long_jump, 288005b261ecSmrg/* 0x84 */ x86emuOp2_long_jump, 288105b261ecSmrg/* 0x85 */ x86emuOp2_long_jump, 288205b261ecSmrg/* 0x86 */ x86emuOp2_long_jump, 288305b261ecSmrg/* 0x87 */ x86emuOp2_long_jump, 288405b261ecSmrg/* 0x88 */ x86emuOp2_long_jump, 288505b261ecSmrg/* 0x89 */ x86emuOp2_long_jump, 288605b261ecSmrg/* 0x8a */ x86emuOp2_long_jump, 288705b261ecSmrg/* 0x8b */ x86emuOp2_long_jump, 288805b261ecSmrg/* 0x8c */ x86emuOp2_long_jump, 288905b261ecSmrg/* 0x8d */ x86emuOp2_long_jump, 289005b261ecSmrg/* 0x8e */ x86emuOp2_long_jump, 289105b261ecSmrg/* 0x8f */ x86emuOp2_long_jump, 289205b261ecSmrg/* 0x90 */ x86emuOp2_set_byte, 289305b261ecSmrg/* 0x91 */ x86emuOp2_set_byte, 289405b261ecSmrg/* 0x92 */ x86emuOp2_set_byte, 289505b261ecSmrg/* 0x93 */ x86emuOp2_set_byte, 289605b261ecSmrg/* 0x94 */ x86emuOp2_set_byte, 289705b261ecSmrg/* 0x95 */ x86emuOp2_set_byte, 289805b261ecSmrg/* 0x96 */ x86emuOp2_set_byte, 289905b261ecSmrg/* 0x97 */ x86emuOp2_set_byte, 290005b261ecSmrg/* 0x98 */ x86emuOp2_set_byte, 290105b261ecSmrg/* 0x99 */ x86emuOp2_set_byte, 290205b261ecSmrg/* 0x9a */ x86emuOp2_set_byte, 290305b261ecSmrg/* 0x9b */ x86emuOp2_set_byte, 290405b261ecSmrg/* 0x9c */ x86emuOp2_set_byte, 290505b261ecSmrg/* 0x9d */ x86emuOp2_set_byte, 290605b261ecSmrg/* 0x9e */ x86emuOp2_set_byte, 290705b261ecSmrg/* 0x9f */ x86emuOp2_set_byte, 290805b261ecSmrg/* 0xa0 */ x86emuOp2_push_FS, 290905b261ecSmrg/* 0xa1 */ x86emuOp2_pop_FS, 29104642e01fSmrg/* 0xa2 */ x86emuOp2_cpuid, 291105b261ecSmrg/* 0xa3 */ x86emuOp2_bt_R, 291205b261ecSmrg/* 0xa4 */ x86emuOp2_shld_IMM, 291305b261ecSmrg/* 0xa5 */ x86emuOp2_shld_CL, 291405b261ecSmrg/* 0xa6 */ x86emuOp2_illegal_op, 291505b261ecSmrg/* 0xa7 */ x86emuOp2_illegal_op, 291605b261ecSmrg/* 0xa8 */ x86emuOp2_push_GS, 291705b261ecSmrg/* 0xa9 */ x86emuOp2_pop_GS, 291805b261ecSmrg/* 0xaa */ x86emuOp2_illegal_op, 291905b261ecSmrg/* 0xab */ x86emuOp2_bts_R, 292005b261ecSmrg/* 0xac */ x86emuOp2_shrd_IMM, 292105b261ecSmrg/* 0xad */ x86emuOp2_shrd_CL, 292205b261ecSmrg/* 0xae */ x86emuOp2_illegal_op, 292305b261ecSmrg/* 0xaf */ x86emuOp2_imul_R_RM, 292435c4bbdfSmrg /* 0xb0 */ x86emuOp2_illegal_op, 292535c4bbdfSmrg /* TODO: cmpxchg */ 292635c4bbdfSmrg /* 0xb1 */ x86emuOp2_illegal_op, 292735c4bbdfSmrg /* TODO: cmpxchg */ 292805b261ecSmrg/* 0xb2 */ x86emuOp2_lss_R_IMM, 292905b261ecSmrg/* 0xb3 */ x86emuOp2_btr_R, 293005b261ecSmrg/* 0xb4 */ x86emuOp2_lfs_R_IMM, 293105b261ecSmrg/* 0xb5 */ x86emuOp2_lgs_R_IMM, 293205b261ecSmrg/* 0xb6 */ x86emuOp2_movzx_byte_R_RM, 293305b261ecSmrg/* 0xb7 */ x86emuOp2_movzx_word_R_RM, 293405b261ecSmrg/* 0xb8 */ x86emuOp2_illegal_op, 293505b261ecSmrg/* 0xb9 */ x86emuOp2_illegal_op, 293605b261ecSmrg/* 0xba */ x86emuOp2_btX_I, 293705b261ecSmrg/* 0xbb */ x86emuOp2_btc_R, 293805b261ecSmrg/* 0xbc */ x86emuOp2_bsf, 293905b261ecSmrg/* 0xbd */ x86emuOp2_bsr, 294005b261ecSmrg/* 0xbe */ x86emuOp2_movsx_byte_R_RM, 294105b261ecSmrg/* 0xbf */ x86emuOp2_movsx_word_R_RM, 294235c4bbdfSmrg /* 0xc0 */ x86emuOp2_illegal_op, 294335c4bbdfSmrg /* TODO: xadd */ 294435c4bbdfSmrg /* 0xc1 */ x86emuOp2_illegal_op, 294535c4bbdfSmrg /* TODO: xadd */ 294605b261ecSmrg/* 0xc2 */ x86emuOp2_illegal_op, 294705b261ecSmrg/* 0xc3 */ x86emuOp2_illegal_op, 294805b261ecSmrg/* 0xc4 */ x86emuOp2_illegal_op, 294905b261ecSmrg/* 0xc5 */ x86emuOp2_illegal_op, 295005b261ecSmrg/* 0xc6 */ x86emuOp2_illegal_op, 295105b261ecSmrg/* 0xc7 */ x86emuOp2_illegal_op, 29524642e01fSmrg/* 0xc8 */ x86emuOp2_bswap, 29534642e01fSmrg/* 0xc9 */ x86emuOp2_bswap, 29544642e01fSmrg/* 0xca */ x86emuOp2_bswap, 29554642e01fSmrg/* 0xcb */ x86emuOp2_bswap, 29564642e01fSmrg/* 0xcc */ x86emuOp2_bswap, 29574642e01fSmrg/* 0xcd */ x86emuOp2_bswap, 29584642e01fSmrg/* 0xce */ x86emuOp2_bswap, 29594642e01fSmrg/* 0xcf */ x86emuOp2_bswap, 296005b261ecSmrg/* 0xd0 */ x86emuOp2_illegal_op, 296105b261ecSmrg/* 0xd1 */ x86emuOp2_illegal_op, 296205b261ecSmrg/* 0xd2 */ x86emuOp2_illegal_op, 296305b261ecSmrg/* 0xd3 */ x86emuOp2_illegal_op, 296405b261ecSmrg/* 0xd4 */ x86emuOp2_illegal_op, 296505b261ecSmrg/* 0xd5 */ x86emuOp2_illegal_op, 296605b261ecSmrg/* 0xd6 */ x86emuOp2_illegal_op, 296705b261ecSmrg/* 0xd7 */ x86emuOp2_illegal_op, 296805b261ecSmrg/* 0xd8 */ x86emuOp2_illegal_op, 296905b261ecSmrg/* 0xd9 */ x86emuOp2_illegal_op, 297005b261ecSmrg/* 0xda */ x86emuOp2_illegal_op, 297105b261ecSmrg/* 0xdb */ x86emuOp2_illegal_op, 297205b261ecSmrg/* 0xdc */ x86emuOp2_illegal_op, 297305b261ecSmrg/* 0xdd */ x86emuOp2_illegal_op, 297405b261ecSmrg/* 0xde */ x86emuOp2_illegal_op, 297505b261ecSmrg/* 0xdf */ x86emuOp2_illegal_op, 297605b261ecSmrg/* 0xe0 */ x86emuOp2_illegal_op, 297705b261ecSmrg/* 0xe1 */ x86emuOp2_illegal_op, 297805b261ecSmrg/* 0xe2 */ x86emuOp2_illegal_op, 297905b261ecSmrg/* 0xe3 */ x86emuOp2_illegal_op, 298005b261ecSmrg/* 0xe4 */ x86emuOp2_illegal_op, 298105b261ecSmrg/* 0xe5 */ x86emuOp2_illegal_op, 298205b261ecSmrg/* 0xe6 */ x86emuOp2_illegal_op, 298305b261ecSmrg/* 0xe7 */ x86emuOp2_illegal_op, 298405b261ecSmrg/* 0xe8 */ x86emuOp2_illegal_op, 298505b261ecSmrg/* 0xe9 */ x86emuOp2_illegal_op, 298605b261ecSmrg/* 0xea */ x86emuOp2_illegal_op, 298705b261ecSmrg/* 0xeb */ x86emuOp2_illegal_op, 298805b261ecSmrg/* 0xec */ x86emuOp2_illegal_op, 298905b261ecSmrg/* 0xed */ x86emuOp2_illegal_op, 299005b261ecSmrg/* 0xee */ x86emuOp2_illegal_op, 299105b261ecSmrg/* 0xef */ x86emuOp2_illegal_op, 299205b261ecSmrg/* 0xf0 */ x86emuOp2_illegal_op, 299305b261ecSmrg/* 0xf1 */ x86emuOp2_illegal_op, 299405b261ecSmrg/* 0xf2 */ x86emuOp2_illegal_op, 299505b261ecSmrg/* 0xf3 */ x86emuOp2_illegal_op, 299605b261ecSmrg/* 0xf4 */ x86emuOp2_illegal_op, 299705b261ecSmrg/* 0xf5 */ x86emuOp2_illegal_op, 299805b261ecSmrg/* 0xf6 */ x86emuOp2_illegal_op, 299905b261ecSmrg/* 0xf7 */ x86emuOp2_illegal_op, 300005b261ecSmrg/* 0xf8 */ x86emuOp2_illegal_op, 300105b261ecSmrg/* 0xf9 */ x86emuOp2_illegal_op, 300205b261ecSmrg/* 0xfa */ x86emuOp2_illegal_op, 300305b261ecSmrg/* 0xfb */ x86emuOp2_illegal_op, 300405b261ecSmrg/* 0xfc */ x86emuOp2_illegal_op, 300505b261ecSmrg/* 0xfd */ x86emuOp2_illegal_op, 300605b261ecSmrg/* 0xfe */ x86emuOp2_illegal_op, 300705b261ecSmrg/* 0xff */ x86emuOp2_illegal_op, 300805b261ecSmrg}; 3009