diff --git a/import/subhook b/import/subhook index e562d10d4..5073ab41a 160000 --- a/import/subhook +++ b/import/subhook @@ -1 +1 @@ -Subproject commit e562d10d4d88f85a8b5475139c68696dfc6bf231 +Subproject commit 5073ab41a88a07eba42877d9285601d319b14067 diff --git a/src/CxbxKrnl/EmuX86.cpp b/src/CxbxKrnl/EmuX86.cpp index c0f4390f9..213df5a36 100644 --- a/src/CxbxKrnl/EmuX86.cpp +++ b/src/CxbxKrnl/EmuX86.cpp @@ -29,7 +29,7 @@ // * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA. // * // * (c) 2002-2003 Aaron Robinson -// * (c) 2016-2018 Luke Usher +// * (c) 2016-2018 Luke Usher // * (c) 2016-2018 Patrick van Logchem // * All rights reserved // * @@ -42,7 +42,7 @@ #pragma comment(lib, "distorm.lib") // Cxbx uses dynamic linking of distorm, which by default chooses for 64 bits offsets : -#define SUPPORT_64BIT_OFFSET +#define SUPPORT_64BIT_OFFSET #include "distorm.h" #include "mnemonics.h" @@ -53,12 +53,12 @@ #include "core/HLE/Intercept.hpp" // for bLLE_GPU #include -#include "devices\Xbox.h" // For g_PCIBus -#include -#include +#include "devices\Xbox.h" // For g_PCIBus +#include +#include #include "Logging.h" -extern uint32_t GetAPUTime(); +extern uint32_t GetAPUTime(); extern std::atomic_bool g_bEnableAllInterrupts; // @@ -119,8 +119,8 @@ void EmuX86_IOWrite(xbaddr addr, uint32_t value, int size) // uint32_t EmuX86_Mem_Read(xbaddr addr, int size) -{ - __try { +{ + __try { switch (size) { case sizeof(uint32_t) : @@ -133,16 +133,16 @@ uint32_t EmuX86_Mem_Read(xbaddr addr, int size) // UNREACHABLE(size); assert(false); return 0; - } + } } __except (true) { - EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "EmuX86_Mem_Read Failed (0x%08X, %d)", addr, size); + EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "EmuX86_Mem_Read Failed (0x%08X, %d)", addr, size); return 0; } } void EmuX86_Mem_Write(xbaddr addr, uint32_t value, int size) -{ +{ __try { switch (size) { case sizeof(uint32_t) : @@ -158,7 +158,7 @@ void EmuX86_Mem_Write(xbaddr addr, uint32_t value, int size) // UNREACHABLE(size); assert(false); return; - } + } } __except (true) { EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "EmuX86_Mem_Write Failed (0x%08X, 0x%08X, %d)", addr, value, size); @@ -245,7 +245,7 @@ int ContextRecordOffsetByRegisterType[/*_RegisterType*/R_DR7 + 1] = { 0 }; // supported by the XBox1's Coppermine Pentium III. // Based on https://maximumcrack.wordpress.com/2011/08/07/fpu-mmx-xmm-and-bbq/ void EmuX86_InitContextRecordOffsetByRegisterType() -{ +{ // Unsupported by XBox CPU : R_RAX, R_RCX, R_RDX, R_RBX, R_RSP, R_RBP, R_RSI, R_RDI, R_R8, R_R9, R_R10, R_R11, R_R12, R_R13, R_R14, R_R15, ContextRecordOffsetByRegisterType[R_EAX] = offsetof(CONTEXT, Eax); ContextRecordOffsetByRegisterType[R_ECX] = offsetof(CONTEXT, Ecx); @@ -342,32 +342,32 @@ void EmuX86_InitContextRecordOffsetByRegisterType() !DWORD SegSs; !BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];*/ } - -std::map g_MemoryBackedRegisters; - -void EmuX86_InitMemoryBackedRegisters() -{ - g_MemoryBackedRegisters[R_CR0] = 0; - g_MemoryBackedRegisters[R_CR2] = 0; - g_MemoryBackedRegisters[R_CR3] = 0; - g_MemoryBackedRegisters[R_CR4] = 0; -} + +std::map g_MemoryBackedRegisters; + +void EmuX86_InitMemoryBackedRegisters() +{ + g_MemoryBackedRegisters[R_CR0] = 0; + g_MemoryBackedRegisters[R_CR2] = 0; + g_MemoryBackedRegisters[R_CR3] = 0; + g_MemoryBackedRegisters[R_CR4] = 0; +} inline void * EmuX86_GetRegisterPointer(const LPEXCEPTION_POINTERS e, const uint8_t reg) -{ +{ int offset = ContextRecordOffsetByRegisterType[reg]; if (offset > 0) { - return (void*)((uintptr_t)(e->ContextRecord) + offset); - } - - // Xbox titles use some registers thatare not accessible in user mode - // They are also not available in the Context/Exception Record, so we can't map them - // Instead, we store the values in a key->value map. - auto it = g_MemoryBackedRegisters.find(reg); - if (it != g_MemoryBackedRegisters.end()) { - return &it->second; - } - + return (void*)((uintptr_t)(e->ContextRecord) + offset); + } + + // Xbox titles use some registers thatare not accessible in user mode + // They are also not available in the Context/Exception Record, so we can't map them + // Instead, we store the values in a key->value map. + auto it = g_MemoryBackedRegisters.find(reg); + if (it != g_MemoryBackedRegisters.end()) { + return &it->second; + } + assert(false); return nullptr; } @@ -375,20 +375,20 @@ inline void * EmuX86_GetRegisterPointer(const LPEXCEPTION_POINTERS e, const uint int EmuX86_DistormRegSize(const uint8_t reg) { switch (reg) { - case R_RAX: return 8; case R_RCX: return 8; case R_RDX: return 8; case R_RBX: return 8; case R_RSP: return 8; case R_RBP: return 8; case R_RSI: return 8; case R_RDI: return 8; case R_R8: return 8; case R_R9: return 8; case R_R10: return 8; case R_R11: return 8; case R_R12: return 8; case R_R13: return 8; case R_R14: return 8; case R_R15: return 8; - case R_EAX: return 4; case R_ECX: return 4; case R_EDX: return 4; case R_EBX: return 4; case R_ESP: return 4; case R_EBP: return 4; case R_ESI: return 4; case R_EDI: return 4; case R_R8D: return 4; case R_R9D: return 4; case R_R10D: return 4; case R_R11D: return 4; case R_R12D: return 4; case R_R13D: return 4; case R_R14D: return 4; case R_R15D: return 4; - case R_AX: return 2; case R_CX: return 2; case R_DX: return 2; case R_BX: return 2; case R_SP: return 2; case R_BP: return 2; case R_SI: return 2; case R_DI: return 2; case R_R8W: return 2; case R_R9W: return 2; case R_R10W: return 2; case R_R11W: return 2; case R_R12W: return 2; case R_R13W: return 2; case R_R14W: return 2; case R_R15W: return 2; - case R_AL: return 1; case R_CL: return 1; case R_DL: return 1; case R_BL: return 1; case R_AH: return 1; case R_CH: return 1; case R_DH: return 1; case R_BH: return 1; case R_R8B: return 1; case R_R9B: return 1; case R_R10B: return 1; case R_R11B: return 1; case R_R12B: return 1; case R_R13B: return 1; case R_R14B: return 1; case R_R15B: return 1; - case R_SPL: return 1; case R_BPL: return 1; case R_SIL: return 1; case R_DIL: return 1; - case R_ES: return 2; case R_CS: return 2; case R_SS: return 2; case R_DS: return 2; case R_FS: return 2; case R_GS: return 2; - case R_RIP: return 8; - case R_ST0: return 10; case R_ST1: return 10; case R_ST2: return 10; case R_ST3: return 10; case R_ST4: return 10; case R_ST5: return 10; case R_ST6: return 10; case R_ST7: return 10; - case R_MM0: return 10; case R_MM1: return 10; case R_MM2: return 10; case R_MM3: return 10; case R_MM4: return 10; case R_MM5: return 10; case R_MM6: return 10; case R_MM7: return 10; - case R_XMM0: return 16; case R_XMM1: return 16; case R_XMM2: return 16; case R_XMM3: return 16; case R_XMM4: return 16; case R_XMM5: return 16; case R_XMM6: return 16; case R_XMM7: return 16; case R_XMM8: return 16; case R_XMM9: return 16; case R_XMM10: return 16; case R_XMM11: return 16; case R_XMM12: return 16; case R_XMM13: return 16; case R_XMM14: return 16; case R_XMM15: return 16; - case R_YMM0: return 16; case R_YMM1: return 16; case R_YMM2: return 16; case R_YMM3: return 16; case R_YMM4: return 16; case R_YMM5: return 16; case R_YMM6: return 16; case R_YMM7: return 16; case R_YMM8: return 16; case R_YMM9: return 16; case R_YMM10: return 16; case R_YMM11: return 16; case R_YMM12: return 16; case R_YMM13: return 16; case R_YMM14: return 16; case R_YMM15: return 16; - case R_CR0: return 4; case R_UNUSED0: return 0; case R_CR2: return 4; case R_CR3: return 4; case R_CR4: return 4; case R_UNUSED1: return 0; case R_UNUSED2: return 0; case R_UNUSED3: return 0; case R_CR8: return 4; - case R_DR0: return 4; case R_DR1: return 4; case R_DR2: return 4; case R_DR3: return 4; case R_UNUSED4: return 0; case R_UNUSED5: return 0; case R_DR6: return 4; case R_DR7: return 4; - default: assert(false); return 0; + case R_RAX: return 8; case R_RCX: return 8; case R_RDX: return 8; case R_RBX: return 8; case R_RSP: return 8; case R_RBP: return 8; case R_RSI: return 8; case R_RDI: return 8; case R_R8: return 8; case R_R9: return 8; case R_R10: return 8; case R_R11: return 8; case R_R12: return 8; case R_R13: return 8; case R_R14: return 8; case R_R15: return 8; + case R_EAX: return 4; case R_ECX: return 4; case R_EDX: return 4; case R_EBX: return 4; case R_ESP: return 4; case R_EBP: return 4; case R_ESI: return 4; case R_EDI: return 4; case R_R8D: return 4; case R_R9D: return 4; case R_R10D: return 4; case R_R11D: return 4; case R_R12D: return 4; case R_R13D: return 4; case R_R14D: return 4; case R_R15D: return 4; + case R_AX: return 2; case R_CX: return 2; case R_DX: return 2; case R_BX: return 2; case R_SP: return 2; case R_BP: return 2; case R_SI: return 2; case R_DI: return 2; case R_R8W: return 2; case R_R9W: return 2; case R_R10W: return 2; case R_R11W: return 2; case R_R12W: return 2; case R_R13W: return 2; case R_R14W: return 2; case R_R15W: return 2; + case R_AL: return 1; case R_CL: return 1; case R_DL: return 1; case R_BL: return 1; case R_AH: return 1; case R_CH: return 1; case R_DH: return 1; case R_BH: return 1; case R_R8B: return 1; case R_R9B: return 1; case R_R10B: return 1; case R_R11B: return 1; case R_R12B: return 1; case R_R13B: return 1; case R_R14B: return 1; case R_R15B: return 1; + case R_SPL: return 1; case R_BPL: return 1; case R_SIL: return 1; case R_DIL: return 1; + case R_ES: return 2; case R_CS: return 2; case R_SS: return 2; case R_DS: return 2; case R_FS: return 2; case R_GS: return 2; + case R_RIP: return 8; + case R_ST0: return 10; case R_ST1: return 10; case R_ST2: return 10; case R_ST3: return 10; case R_ST4: return 10; case R_ST5: return 10; case R_ST6: return 10; case R_ST7: return 10; + case R_MM0: return 10; case R_MM1: return 10; case R_MM2: return 10; case R_MM3: return 10; case R_MM4: return 10; case R_MM5: return 10; case R_MM6: return 10; case R_MM7: return 10; + case R_XMM0: return 16; case R_XMM1: return 16; case R_XMM2: return 16; case R_XMM3: return 16; case R_XMM4: return 16; case R_XMM5: return 16; case R_XMM6: return 16; case R_XMM7: return 16; case R_XMM8: return 16; case R_XMM9: return 16; case R_XMM10: return 16; case R_XMM11: return 16; case R_XMM12: return 16; case R_XMM13: return 16; case R_XMM14: return 16; case R_XMM15: return 16; + case R_YMM0: return 16; case R_YMM1: return 16; case R_YMM2: return 16; case R_YMM3: return 16; case R_YMM4: return 16; case R_YMM5: return 16; case R_YMM6: return 16; case R_YMM7: return 16; case R_YMM8: return 16; case R_YMM9: return 16; case R_YMM10: return 16; case R_YMM11: return 16; case R_YMM12: return 16; case R_YMM13: return 16; case R_YMM14: return 16; case R_YMM15: return 16; + case R_CR0: return 4; case R_UNUSED0: return 0; case R_CR2: return 4; case R_CR3: return 4; case R_CR4: return 4; case R_UNUSED1: return 0; case R_UNUSED2: return 0; case R_UNUSED3: return 0; case R_CR8: return 4; + case R_DR0: return 4; case R_DR1: return 4; case R_DR2: return 4; case R_DR3: return 4; case R_UNUSED4: return 0; case R_UNUSED5: return 0; case R_DR6: return 4; case R_DR7: return 4; + default: assert(false); return 0; } } @@ -451,14 +451,14 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& { opAddr.size = info.ops[operand].size / 8; // Convert size in bits into bytes switch (info.ops[operand].type) { - case O_NONE: // operand is to be ignored. + case O_NONE: // operand is to be ignored. { assert(opAddr.size == 0); // Ignore O_NONE operand return false; } - case O_REG: // index holds global register index. + case O_REG: // index holds global register index. { assert(opAddr.size == EmuX86_DistormRegSize(info.ops[operand].index)); @@ -466,7 +466,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& opAddr.addr = (xbaddr)EmuX86_GetRegisterPointer(e, info.ops[operand].index); return true; } - case O_IMM: // instruction.imm. + case O_IMM: // instruction.imm. { assert(opAddr.size == sizeof(uint8_t) || opAddr.size == sizeof(uint16_t) || opAddr.size == sizeof(uint32_t)); @@ -474,7 +474,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& opAddr.addr = (xbaddr)(&info.imm); return true; } - case O_IMM1: // instruction.imm.ex.i1. + case O_IMM1: // instruction.imm.ex.i1. { assert(opAddr.size == sizeof(uint8_t) || opAddr.size == sizeof(uint16_t) || opAddr.size == sizeof(uint32_t)); @@ -482,7 +482,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& opAddr.addr = (xbaddr)(&info.imm.ex.i1); return true; } - case O_IMM2: // instruction.imm.ex.i2. + case O_IMM2: // instruction.imm.ex.i2. { assert(opAddr.size == sizeof(uint8_t) || opAddr.size == sizeof(uint16_t) || opAddr.size == sizeof(uint32_t)); @@ -490,7 +490,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& opAddr.addr = (xbaddr)(&info.imm.ex.i2); return true; } - case O_DISP: // memory dereference with displacement only, instruction.disp. + case O_DISP: // memory dereference with displacement only, instruction.disp. { assert(opAddr.size == sizeof(uint32_t)); @@ -498,7 +498,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& opAddr.addr = EmuX86_Distorm_read_disp(info); return true; } - case O_SMEM: // simple memory dereference with optional displacement(a single register memory dereference). + case O_SMEM: // simple memory dereference with optional displacement(a single register memory dereference). { assert(opAddr.size == 0 || opAddr.size == sizeof(uint8_t) || opAddr.size == sizeof(uint16_t) || opAddr.size == sizeof(uint32_t)); // TODO : How to handle size == 0 further on? @@ -507,7 +507,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& + EmuX86_Distorm_read_disp(info); return true; } - case O_MEM: // complex memory dereference(optional fields : s / i / b / disp). + case O_MEM: // complex memory dereference(optional fields : s / i / b / disp). { assert(opAddr.size == 0 || opAddr.size == sizeof(uint8_t) || opAddr.size == sizeof(uint16_t) || opAddr.size == sizeof(uint32_t)); // TODO : How to handle size == 0 further on? assert(info.scale < 3 || info.scale == 4 || info.scale == 8); // Assume scale is either 0, 1, 2, 4 or 8 @@ -523,7 +523,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& return true; } - case O_PC: // the relative address of a branch instruction(instruction.imm.addr). + case O_PC: // the relative address of a branch instruction(instruction.imm.addr). { assert(opAddr.size == sizeof(uint8_t) || opAddr.size == sizeof(uint32_t)); @@ -531,7 +531,7 @@ bool EmuX86_Operand_Addr_ForReadOnly(const LPEXCEPTION_POINTERS e, const _DInst& opAddr.addr = (xbaddr)e->ContextRecord->Eip + (xbaddr)INSTRUCTION_GET_TARGET(&info); return true; } - case O_PTR: // the absolute target address of a far branch instruction(instruction.imm.ptr.seg / off). + case O_PTR: // the absolute target address of a far branch instruction(instruction.imm.ptr.seg / off). { assert(opAddr.size == 0); @@ -672,40 +672,40 @@ inline void EmuX86_SetFlags_OSZAP ); } -inline bool EmuX86_HasFlag(LPEXCEPTION_POINTERS e, DWORD flag) -{ - return (e->ContextRecord->EFlags & flag); -} - -inline bool EmuX86_HasFlag_AF(LPEXCEPTION_POINTERS e) -{ - return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_AF)); -} +inline bool EmuX86_HasFlag(LPEXCEPTION_POINTERS e, DWORD flag) +{ + return (e->ContextRecord->EFlags & flag); +} -inline bool EmuX86_HasFlag_CF(LPEXCEPTION_POINTERS e) -{ - return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_CF)); -} +inline bool EmuX86_HasFlag_AF(LPEXCEPTION_POINTERS e) +{ + return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_AF)); +} -inline bool EmuX86_HasFlag_OF(LPEXCEPTION_POINTERS e) -{ - return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_OF)); -} +inline bool EmuX86_HasFlag_CF(LPEXCEPTION_POINTERS e) +{ + return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_CF)); +} -inline bool EmuX86_HasFlag_PF(LPEXCEPTION_POINTERS e) -{ - return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_PF)); -} +inline bool EmuX86_HasFlag_OF(LPEXCEPTION_POINTERS e) +{ + return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_OF)); +} -inline bool EmuX86_HasFlag_SF(LPEXCEPTION_POINTERS e) -{ - return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_SF)); -} +inline bool EmuX86_HasFlag_PF(LPEXCEPTION_POINTERS e) +{ + return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_PF)); +} -inline bool EmuX86_HasFlag_ZF(LPEXCEPTION_POINTERS e) -{ - return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_ZF)); -} +inline bool EmuX86_HasFlag_SF(LPEXCEPTION_POINTERS e) +{ + return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_SF)); +} + +inline bool EmuX86_HasFlag_ZF(LPEXCEPTION_POINTERS e) +{ + return EmuX86_HasFlag(e, BITMASK(EMUX86_EFLAG_ZF)); +} // EFLAGS Cross-Reference : http://datasheets.chipdb.org/Intel/x86/Intel%20Architecture/EFLAGS.PDF @@ -767,21 +767,21 @@ bool EmuX86_Opcode_ADD(LPEXCEPTION_POINTERS e, _DInst& info) if (info.ops[0].size > info.ops[1].size) { SignExtend32(src, info.ops[1].size); } - - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - add eax, src // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + add eax, src // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write back the result EmuX86_Addr_Write(opAddr, result); @@ -807,37 +807,37 @@ bool EmuX86_Opcode_AND(LPEXCEPTION_POINTERS e, _DInst& info) SignExtend32(src, info.ops[1].size); } - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - and eax, src // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + and eax, src // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write back the result EmuX86_Addr_Write(opAddr, result); return true; } - -void EmuX86_Opcode_CDQ(LPEXCEPTION_POINTERS e, _DInst& info) -{ - e->ContextRecord->Edx = (e->ContextRecord->Eax & 0x80000000) ? 0xFFFFFFFF : 0; -} - -void EmuX86_Opcode_CLI() + +void EmuX86_Opcode_CDQ(LPEXCEPTION_POINTERS e, _DInst& info) +{ + e->ContextRecord->Edx = (e->ContextRecord->Eax & 0x80000000) ? 0xFFFFFFFF : 0; +} + +void EmuX86_Opcode_CLI() { g_bEnableAllInterrupts = false; -} - +} + bool EmuX86_Opcode_CMP(LPEXCEPTION_POINTERS e, _DInst& info) { // Read value from Source and Destination @@ -852,18 +852,18 @@ bool EmuX86_Opcode_CMP(LPEXCEPTION_POINTERS e, _DInst& info) if (info.ops[0].size > info.ops[1].size) { SignExtend32(src, info.ops[1].size); } - - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - cmp eax, src // perform the operation, this updates eflags for us! - pushfd // push the updated host flags onto the stack + + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + cmp eax, src // perform the operation, this updates eflags for us! + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags + + // Write back the flags e->ContextRecord->EFlags = eflags; return true; @@ -899,18 +899,18 @@ bool EmuX86_Opcode_CMPXCHG(LPEXCEPTION_POINTERS e, _DInst& info) e->ContextRecord->Eax = (e->ContextRecord->Eax & ~mask) | (dest & mask); } - // Perform arithmatic operation for flag calculation - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, eaxVal - cmp eax, dest // perform the operation, this updates eflags for us! - pushfd // push the updated host flags onto the stack + // Perform arithmatic operation for flag calculation + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, eaxVal + cmp eax, dest // perform the operation, this updates eflags for us! + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags + + // Write back the flags e->ContextRecord->EFlags = eflags; return true; @@ -971,20 +971,20 @@ bool EmuX86_Opcode_DEC(LPEXCEPTION_POINTERS e, _DInst& info) uint32_t dest = EmuX86_Addr_Read(opAddr); - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - dec eax // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + dec eax // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write result back EmuX86_Addr_Write(opAddr, static_cast(result)); @@ -1019,48 +1019,48 @@ bool EmuX86_Opcode_INC(LPEXCEPTION_POINTERS e, _DInst& info) uint32_t dest = EmuX86_Addr_Read(opAddr); - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - inc eax // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + inc eax // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write result back EmuX86_Addr_Write(opAddr, static_cast(result)); return true; -} +} bool EmuX86_Opcode_JMP(LPEXCEPTION_POINTERS e, _DInst& info) { - OperandAddress opAddr; - if (!EmuX86_Operand_Addr_ForReadOnly(e, info, 0, OUT opAddr)) - assert(false); - - e->ContextRecord->Eip = opAddr.addr; + OperandAddress opAddr; + if (!EmuX86_Operand_Addr_ForReadOnly(e, info, 0, OUT opAddr)) + assert(false); + + e->ContextRecord->Eip = opAddr.addr; return true; } - -// Jump if condition is met + +// Jump if condition is met // https://c9x.me/x86/html/file_module_x86_id_146.html // Returns true if branch was taken bool EmuX86_Opcode_Jcc(LPEXCEPTION_POINTERS e, _DInst& info, bool condition) { - if (condition) - return EmuX86_Opcode_JMP(e, info); + if (condition) + return EmuX86_Opcode_JMP(e, info); return false; } - + bool EmuX86_Opcode_LEA(LPEXCEPTION_POINTERS e, _DInst& info) { // LEA reads effective address from source operand : @@ -1142,9 +1142,9 @@ bool EmuX86_Opcode_MOVZX(LPEXCEPTION_POINTERS e, _DInst& info) return true; } - + bool EmuX86_Opcode_NEG(LPEXCEPTION_POINTERS e, _DInst& info) -{ +{ // NEG reads and writes the same operand : OperandAddress opAddr; if (!EmuX86_Operand_Addr_ForReadWrite(e, info, 0, OUT opAddr)) @@ -1169,8 +1169,8 @@ bool EmuX86_Opcode_NEG(LPEXCEPTION_POINTERS e, _DInst& info) /*EMUX86_EFLAG_CF*/(dest != 0)); return true; -} - +} + bool EmuX86_Opcode_NOT(LPEXCEPTION_POINTERS e, _DInst& info) { // NOT reads and writes the same operand : @@ -1179,19 +1179,19 @@ bool EmuX86_Opcode_NOT(LPEXCEPTION_POINTERS e, _DInst& info) return false; uint32_t dest = EmuX86_Addr_Read(opAddr); - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - not eax // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + not eax // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags + + // Write back the flags e->ContextRecord->EFlags = eflags; // Write back the result @@ -1200,7 +1200,7 @@ bool EmuX86_Opcode_NOT(LPEXCEPTION_POINTERS e, _DInst& info) // Flags are not effected return true; -} +} bool EmuX86_Opcode_OR(LPEXCEPTION_POINTERS e, _DInst& info) { @@ -1217,22 +1217,22 @@ bool EmuX86_Opcode_OR(LPEXCEPTION_POINTERS e, _DInst& info) uint32_t dest = EmuX86_Addr_Read(opAddr); if (info.ops[0].size > info.ops[1].size) { SignExtend32(src, info.ops[1].size); - } + } - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - or eax, src // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + or eax, src // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write back the result EmuX86_Addr_Write(opAddr, result); @@ -1258,41 +1258,41 @@ bool EmuX86_Opcode_OUT(LPEXCEPTION_POINTERS e, _DInst& info) return true; } - -// https://c9x.me/x86/html/file_module_x86_id_248.html -bool EmuX86_Opcode_POP(LPEXCEPTION_POINTERS e, _DInst& info) -{ - // Recognize POP ESP (which increments BEFORE reading from stack) : - bool bAccessesESP = (info.ops[0].type == O_REG) && (info.ops[0].index == R_ESP); - uint32_t value; - if (bAccessesESP) { - e->ContextRecord->Esp += sizeof(uint32_t); - value = EmuX86_Mem_Read(e->ContextRecord->Esp, sizeof(uint32_t)); - } - else { - value = EmuX86_Mem_Read(e->ContextRecord->Esp, sizeof(uint32_t)); - e->ContextRecord->Esp += sizeof(uint32_t); - } - +// https://c9x.me/x86/html/file_module_x86_id_248.html +bool EmuX86_Opcode_POP(LPEXCEPTION_POINTERS e, _DInst& info) +{ + // Recognize POP ESP (which increments BEFORE reading from stack) : + bool bAccessesESP = (info.ops[0].type == O_REG) && (info.ops[0].index == R_ESP); + uint32_t value; + + if (bAccessesESP) { + e->ContextRecord->Esp += sizeof(uint32_t); + value = EmuX86_Mem_Read(e->ContextRecord->Esp, sizeof(uint32_t)); + } + else { + value = EmuX86_Mem_Read(e->ContextRecord->Esp, sizeof(uint32_t)); + e->ContextRecord->Esp += sizeof(uint32_t); + } + if (!EmuX86_Operand_Write(e, info, 0, value)) - return false; - - return true; -} + return false; -bool EmuX86_Opcode_PUSH(LPEXCEPTION_POINTERS e, _DInst& info) -{ - uint32_t value; + return true; +} + +bool EmuX86_Opcode_PUSH(LPEXCEPTION_POINTERS e, _DInst& info) +{ + uint32_t value; if (!EmuX86_Operand_Read(e, info, 0, &value)) - return false; - - e->ContextRecord->Esp -= sizeof(uint32_t); - EmuX86_Mem_Write(e->ContextRecord->Esp, value, sizeof(uint32_t)); - return true; -} + return false; -ULONGLONG CxbxRdTsc(bool xbox); // implemented in EmuKrnlKe.cpp + e->ContextRecord->Esp -= sizeof(uint32_t); + EmuX86_Mem_Write(e->ContextRecord->Esp, value, sizeof(uint32_t)); + return true; +} + +ULONGLONG CxbxRdTsc(bool xbox); // implemented in EmuKrnlKe.cpp void EmuX86_Opcode_RDTSC(LPEXCEPTION_POINTERS e) { // Avoid the overhead of xboxkrnl::KeQueryPerformanceCounter, @@ -1302,9 +1302,9 @@ void EmuX86_Opcode_RDTSC(LPEXCEPTION_POINTERS e) e->ContextRecord->Eax = PerformanceCount.LowPart; e->ContextRecord->Edx = PerformanceCount.HighPart; } - -bool EmuX86_Opcode_SAR(LPEXCEPTION_POINTERS e, _DInst& info) -{ + +bool EmuX86_Opcode_SAR(LPEXCEPTION_POINTERS e, _DInst& info) +{ // Read value from Source and Destination uint32_t src = 0; if (!EmuX86_Operand_Read(e, info, 1, &src)) @@ -1316,30 +1316,30 @@ bool EmuX86_Opcode_SAR(LPEXCEPTION_POINTERS e, _DInst& info) return false; uint32_t dest = EmuX86_Addr_Read(opAddr); - - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - uint8_t byteSrc = src; - - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - mov cl, byteSrc - sar eax, cl // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + uint8_t byteSrc = src; + + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + mov cl, byteSrc + sar eax, cl // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; - + + // Write back the flags + e->ContextRecord->EFlags = eflags; + // Write result back EmuX86_Addr_Write(opAddr, static_cast(result)); return true; -} +} bool EmuX86_Opcode_SBB(LPEXCEPTION_POINTERS e, _DInst& info) { @@ -1359,29 +1359,29 @@ bool EmuX86_Opcode_SBB(LPEXCEPTION_POINTERS e, _DInst& info) SignExtend32(src, info.ops[1].size); } - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - sbb eax, src // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + sbb eax, src // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write result back EmuX86_Addr_Write(opAddr, static_cast(result)); return true; } - -// Set Byte on Condition -// https://c9x.me/x86/html/file_module_x86_id_288.html + +// Set Byte on Condition +// https://c9x.me/x86/html/file_module_x86_id_288.html inline bool EmuX86_Opcode_SETcc(LPEXCEPTION_POINTERS e, _DInst& info, bool condition) { uint8_t value = (condition) ? 1 : 0; @@ -1403,25 +1403,25 @@ bool EmuX86_Opcode_SHL(LPEXCEPTION_POINTERS e, _DInst& info) uint32_t dest = EmuX86_Addr_Read(opAddr); - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - uint8_t byteSrc = src; - - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - mov cl, byteSrc - shl eax, cl // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + uint8_t byteSrc = src; + + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + mov cl, byteSrc + shl eax, cl // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; - + + // Write back the flags + e->ContextRecord->EFlags = eflags; + // Write result back EmuX86_Addr_Write(opAddr, static_cast(result)); @@ -1443,32 +1443,32 @@ bool EmuX86_Opcode_SHR(LPEXCEPTION_POINTERS e, _DInst& info) uint32_t dest = EmuX86_Addr_Read(opAddr); - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - uint8_t byteSrc = src; - - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - mov cl, byteSrc - shr eax, cl // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + uint8_t byteSrc = src; + + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + mov cl, byteSrc + shr eax, cl // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; - + + // Write back the flags + e->ContextRecord->EFlags = eflags; + // Write result back EmuX86_Addr_Write(opAddr, static_cast(result)); return true; } -void EmuX86_Opcode_STI() +void EmuX86_Opcode_STI() { g_bEnableAllInterrupts = true; } @@ -1490,21 +1490,21 @@ bool EmuX86_Opcode_SUB(LPEXCEPTION_POINTERS e, _DInst& info) if (info.ops[0].size > info.ops[1].size) { SignExtend32(src, info.ops[1].size); } - - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - sub eax, src // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + sub eax, src // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write result back EmuX86_Addr_Write(opAddr, static_cast(result)); @@ -1524,23 +1524,23 @@ bool EmuX86_Opcode_TEST(LPEXCEPTION_POINTERS e, _DInst& info) if (!EmuX86_Operand_Read(e, info, 1, &src)) return false; - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - test eax, src // perform the operation, this updates eflags for us! - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + test eax, src // perform the operation, this updates eflags for us! + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags + + // Write back the flags e->ContextRecord->EFlags = eflags; return true; -} - +} + bool EmuX86_Opcode_XOR(LPEXCEPTION_POINTERS e, _DInst& info) { // Read value from Source and Destination @@ -1559,28 +1559,28 @@ bool EmuX86_Opcode_XOR(LPEXCEPTION_POINTERS e, _DInst& info) SignExtend32(src, info.ops[1].size); } - uint32_t result = 0; - uint32_t eflags = e->ContextRecord->EFlags; - __asm { - push eflags // push context eflags on the stack - popfd // pop context eflags into host eflags - mov eax, dest - xor eax, src // perform the operation, this updates eflags for us! - mov result, eax - pushfd // push the updated host flags onto the stack + uint32_t result = 0; + uint32_t eflags = e->ContextRecord->EFlags; + __asm { + push eflags // push context eflags on the stack + popfd // pop context eflags into host eflags + mov eax, dest + xor eax, src // perform the operation, this updates eflags for us! + mov result, eax + pushfd // push the updated host flags onto the stack pop eflags // pop the updated host flags back into our eflags register } - - // Write back the flags - e->ContextRecord->EFlags = eflags; + + // Write back the flags + e->ContextRecord->EFlags = eflags; // Write back the result EmuX86_Addr_Write(opAddr, result); return true; -} - +} + bool EmuX86_DecodeOpcode(const uint8_t *Eip, _DInst &info) { unsigned int decodedInstructionsCount = 0; @@ -1597,29 +1597,29 @@ bool EmuX86_DecodeOpcode(const uint8_t *Eip, _DInst &info) // halt cleanly after reaching maxInstructions 1. So instead, just call distorm : distorm_decompose(&ci, &info, /*maxInstructions=*/1, &decodedInstructionsCount); // and check if it successfully decoded one instruction : - return (decodedInstructionsCount == 1); + return (decodedInstructionsCount == 1); } - -const char *Distorm_RegStrings[/*_RegisterType*/] = { - "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", - "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D", - "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W", - "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B", - "SPL", "BPL", "SIL", "DIL", - "ES", "CS", "SS", "DS", "FS", "GS", - "RIP", - "ST0", "ST1", "ST2", "ST3", "ST4", "ST5", "ST6", "ST7", - "MM0", "MM1", "MM2", "MM3", "MM4", "MM5", "MM6", "MM7", - "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15", - "YMM0", "YMM1", "YMM2", "YMM3", "YMM4", "YMM5", "YMM6", "YMM7", "YMM8", "YMM9", "YMM10", "YMM11", "YMM12", "YMM13", "YMM14", "YMM15", - "CR0", "UNUSED0", "CR2", "CR3", "CR4", "UNUSED1", "UNUSED2", "UNUSED3", "CR8", - "DR0", "DR1", "DR2", "DR3", "UNUSED4", "UNUSED5", "DR6", "DR7", -}; - -char *Distorm_OpcodeString(const int opcode) -{ - // Note : Distorm's GET_MNEMONIC_NAME() doesn't link somehow... - switch (opcode) { + +const char *Distorm_RegStrings[/*_RegisterType*/] = { + "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", + "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D", + "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W", + "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B", + "SPL", "BPL", "SIL", "DIL", + "ES", "CS", "SS", "DS", "FS", "GS", + "RIP", + "ST0", "ST1", "ST2", "ST3", "ST4", "ST5", "ST6", "ST7", + "MM0", "MM1", "MM2", "MM3", "MM4", "MM5", "MM6", "MM7", + "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15", + "YMM0", "YMM1", "YMM2", "YMM3", "YMM4", "YMM5", "YMM6", "YMM7", "YMM8", "YMM9", "YMM10", "YMM11", "YMM12", "YMM13", "YMM14", "YMM15", + "CR0", "UNUSED0", "CR2", "CR3", "CR4", "UNUSED1", "UNUSED2", "UNUSED3", "CR8", + "DR0", "DR1", "DR2", "DR3", "UNUSED4", "UNUSED5", "DR6", "DR7", +}; + +char *Distorm_OpcodeString(const int opcode) +{ + // Note : Distorm's GET_MNEMONIC_NAME() doesn't link somehow... + switch (opcode) { case I_AAA: return "AAA"; case I_AAD: return "AAD"; case I_AAM: return "AAM"; @@ -1627,1265 +1627,1265 @@ char *Distorm_OpcodeString(const int opcode) case I_ADC: return "ADC"; case I_ADD: return "ADD"; case I_ADDPD: return "ADDPD"; - case I_ADDPS: return "ADDPS"; + case I_ADDPS: return "ADDPS"; case I_ADDSD: return "ADDSD"; case I_ADDSS: return "ADDSS"; case I_ADDSUBPD: return "ADDSUBPD"; case I_ADDSUBPS: return "ADDSUBPS"; - case I_AESDEC: return "AESDEC"; + case I_AESDEC: return "AESDEC"; case I_AESDECLAST: return "AESDECLAST"; case I_AESENC: return "AESENC"; case I_AESENCLAST: return "AESENCLAST"; - case I_AESIMC: return "AESIMC"; + case I_AESIMC: return "AESIMC"; case I_AESKEYGENASSIST: return "AESKEYGENASSIST"; case I_AND: return "AND"; case I_ANDNPD: return "ANDNPD"; case I_ANDNPS: return "ANDNPS"; - case I_ANDPD: return "ANDPD"; + case I_ANDPD: return "ANDPD"; case I_ANDPS: return "ANDPS"; case I_ARPL: return "ARPL"; case I_BLENDPD: return "BLENDPD"; case I_BLENDPS: return "BLENDPS"; - case I_BLENDVPD: return "BLENDVPD"; + case I_BLENDVPD: return "BLENDVPD"; case I_BLENDVPS: return "BLENDVPS"; case I_BOUND: return "BOUND"; case I_BSF: return "BSF"; case I_BSR: return "BSR"; - case I_BSWAP: return "BSWAP"; + case I_BSWAP: return "BSWAP"; case I_BT: return "BT"; case I_BTC: return "BTC"; case I_BTR: return "BTR"; case I_BTS: return "BTS"; case I_CALL: return "CALL"; - case I_CALL_FAR: return "CALL_FAR"; + case I_CALL_FAR: return "CALL_FAR"; case I_CBW: return "CBW"; case I_CDQ: return "CDQ"; case I_CDQE: return "CDQE"; case I_CLC: return "CLC"; case I_CLD: return "CLD"; - case I_CLFLUSH: return "CLFLUSH"; + case I_CLFLUSH: return "CLFLUSH"; case I_CLGI: return "CLGI"; case I_CLI: return "CLI"; case I_CLTS: return "CLTS"; case I_CMC: return "CMC"; case I_CMOVA: return "CMOVA"; - case I_CMOVAE: return "CMOVAE"; + case I_CMOVAE: return "CMOVAE"; case I_CMOVB: return "CMOVB"; case I_CMOVBE: return "CMOVBE"; case I_CMOVG: return "CMOVG"; case I_CMOVGE: return "CMOVGE"; - case I_CMOVL: return "CMOVL"; + case I_CMOVL: return "CMOVL"; case I_CMOVLE: return "CMOVLE"; case I_CMOVNO: return "CMOVNO"; case I_CMOVNP: return "CMOVNP"; case I_CMOVNS: return "CMOVNS"; - case I_CMOVNZ: return "CMOVNZ"; + case I_CMOVNZ: return "CMOVNZ"; case I_CMOVO: return "CMOVO"; case I_CMOVP: return "CMOVP"; case I_CMOVS: return "CMOVS"; case I_CMOVZ: return "CMOVZ"; - case I_CMP: return "CMP"; + case I_CMP: return "CMP"; case I_CMPEQPD: return "CMPEQPD"; case I_CMPEQPS: return "CMPEQPS"; case I_CMPEQSD: return "CMPEQSD"; case I_CMPEQSS: return "CMPEQSS"; - case I_CMPLEPD: return "CMPLEPD"; + case I_CMPLEPD: return "CMPLEPD"; case I_CMPLEPS: return "CMPLEPS"; case I_CMPLESD: return "CMPLESD"; case I_CMPLESS: return "CMPLESS"; case I_CMPLTPD: return "CMPLTPD"; - case I_CMPLTPS: return "CMPLTPS"; + case I_CMPLTPS: return "CMPLTPS"; case I_CMPLTSD: return "CMPLTSD"; case I_CMPLTSS: return "CMPLTSS"; case I_CMPNEQPD: return "CMPNEQPD"; case I_CMPNEQPS: return "CMPNEQPS"; - case I_CMPNEQSD: return "CMPNEQSD"; + case I_CMPNEQSD: return "CMPNEQSD"; case I_CMPNEQSS: return "CMPNEQSS"; case I_CMPNLEPD: return "CMPNLEPD"; case I_CMPNLEPS: return "CMPNLEPS"; - case I_CMPNLESD: return "CMPNLESD"; + case I_CMPNLESD: return "CMPNLESD"; case I_CMPNLESS: return "CMPNLESS"; case I_CMPNLTPD: return "CMPNLTPD"; case I_CMPNLTPS: return "CMPNLTPS"; - case I_CMPNLTSD: return "CMPNLTSD"; + case I_CMPNLTSD: return "CMPNLTSD"; case I_CMPNLTSS: return "CMPNLTSS"; case I_CMPORDPD: return "CMPORDPD"; case I_CMPORDPS: return "CMPORDPS"; - case I_CMPORDSD: return "CMPORDSD"; + case I_CMPORDSD: return "CMPORDSD"; case I_CMPORDSS: return "CMPORDSS"; case I_CMPS: return "CMPS"; case I_CMPUNORDPD: return "CMPUNORDPD"; case I_CMPUNORDPS: return "CMPUNORDPS"; - case I_CMPUNORDSD: return "CMPUNORDSD"; + case I_CMPUNORDSD: return "CMPUNORDSD"; case I_CMPUNORDSS: return "CMPUNORDSS"; case I_CMPXCHG: return "CMPXCHG"; case I_CMPXCHG16B: return "CMPXCHG16B"; - case I_CMPXCHG8B: return "CMPXCHG8B"; + case I_CMPXCHG8B: return "CMPXCHG8B"; case I_COMISD: return "COMISD"; case I_COMISS: return "COMISS"; case I_CPUID: return "CPUID"; case I_CQO: return "CQO"; - case I_CRC32: return "CRC32"; + case I_CRC32: return "CRC32"; case I_CVTDQ2PD: return "CVTDQ2PD"; case I_CVTDQ2PS: return "CVTDQ2PS"; case I_CVTPD2DQ: return "CVTPD2DQ"; case I_CVTPD2PI: return "CVTPD2PI"; - case I_CVTPD2PS: return "CVTPD2PS"; + case I_CVTPD2PS: return "CVTPD2PS"; case I_CVTPH2PS: return "CVTPH2PS"; case I_CVTPI2PD: return "CVTPI2PD"; case I_CVTPI2PS: return "CVTPI2PS"; - case I_CVTPS2DQ: return "CVTPS2DQ"; + case I_CVTPS2DQ: return "CVTPS2DQ"; case I_CVTPS2PD: return "CVTPS2PD"; case I_CVTPS2PH: return "CVTPS2PH"; case I_CVTPS2PI: return "CVTPS2PI"; - case I_CVTSD2SI: return "CVTSD2SI"; + case I_CVTSD2SI: return "CVTSD2SI"; case I_CVTSD2SS: return "CVTSD2SS"; case I_CVTSI2SD: return "CVTSI2SD"; case I_CVTSI2SS: return "CVTSI2SS"; - case I_CVTSS2SD: return "CVTSS2SD"; + case I_CVTSS2SD: return "CVTSS2SD"; case I_CVTSS2SI: return "CVTSS2SI"; case I_CVTTPD2DQ: return "CVTTPD2DQ"; case I_CVTTPD2PI: return "CVTTPD2PI"; - case I_CVTTPS2DQ: return "CVTTPS2DQ"; + case I_CVTTPS2DQ: return "CVTTPS2DQ"; case I_CVTTPS2PI: return "CVTTPS2PI"; case I_CVTTSD2SI: return "CVTTSD2SI"; case I_CVTTSS2SI: return "CVTTSS2SI"; - case I_CWD: return "CWD"; + case I_CWD: return "CWD"; case I_CWDE: return "CWDE"; case I_DAA: return "DAA"; case I_DAS: return "DAS"; case I_DEC: return "DEC"; case I_DIV: return "DIV"; - case I_DIVPD: return "DIVPD"; + case I_DIVPD: return "DIVPD"; case I_DIVPS: return "DIVPS"; case I_DIVSD: return "DIVSD"; case I_DIVSS: return "DIVSS"; case I_DPPD: return "DPPD"; - case I_DPPS: return "DPPS"; + case I_DPPS: return "DPPS"; case I_EMMS: return "EMMS"; case I_ENTER: return "ENTER"; case I_EXTRACTPS: return "EXTRACTPS"; case I_EXTRQ: return "EXTRQ"; - case I_F2XM1: return "F2XM1"; + case I_F2XM1: return "F2XM1"; case I_FABS: return "FABS"; case I_FADD: return "FADD"; case I_FADDP: return "FADDP"; case I_FBLD: return "FBLD"; - case I_FBSTP: return "FBSTP"; + case I_FBSTP: return "FBSTP"; case I_FCHS: return "FCHS"; case I_FCLEX: return "FCLEX"; case I_FCMOVB: return "FCMOVB"; case I_FCMOVBE: return "FCMOVBE"; - case I_FCMOVE: return "FCMOVE"; + case I_FCMOVE: return "FCMOVE"; case I_FCMOVNB: return "FCMOVNB"; case I_FCMOVNBE: return "FCMOVNBE"; case I_FCMOVNE: return "FCMOVNE"; case I_FCMOVNU: return "FCMOVNU"; - case I_FCMOVU: return "FCMOVU"; + case I_FCMOVU: return "FCMOVU"; case I_FCOM: return "FCOM"; case I_FCOMI: return "FCOMI"; case I_FCOMIP: return "FCOMIP"; case I_FCOMP: return "FCOMP"; - case I_FCOMPP: return "FCOMPP"; + case I_FCOMPP: return "FCOMPP"; case I_FCOS: return "FCOS"; case I_FDECSTP: return "FDECSTP"; case I_FDIV: return "FDIV"; case I_FDIVP: return "FDIVP"; - case I_FDIVR: return "FDIVR"; + case I_FDIVR: return "FDIVR"; case I_FDIVRP: return "FDIVRP"; case I_FEDISI: return "FEDISI"; case I_FEMMS: return "FEMMS"; case I_FENI: return "FENI"; - case I_FFREE: return "FFREE"; + case I_FFREE: return "FFREE"; case I_FIADD: return "FIADD"; case I_FICOM: return "FICOM"; case I_FICOMP: return "FICOMP"; case I_FIDIV: return "FIDIV"; - case I_FIDIVR: return "FIDIVR"; + case I_FIDIVR: return "FIDIVR"; case I_FILD: return "FILD"; case I_FIMUL: return "FIMUL"; case I_FINCSTP: return "FINCSTP"; case I_FINIT: return "FINIT"; - case I_FIST: return "FIST"; + case I_FIST: return "FIST"; case I_FISTP: return "FISTP"; case I_FISTTP: return "FISTTP"; case I_FISUB: return "FISUB"; case I_FISUBR: return "FISUBR"; - case I_FLD: return "FLD"; + case I_FLD: return "FLD"; case I_FLD1: return "FLD1"; case I_FLDCW: return "FLDCW"; case I_FLDENV: return "FLDENV"; case I_FLDL2E: return "FLDL2E"; - case I_FLDL2T: return "FLDL2T"; + case I_FLDL2T: return "FLDL2T"; case I_FLDLG2: return "FLDLG2"; case I_FLDLN2: return "FLDLN2"; case I_FLDPI: return "FLDPI"; case I_FLDZ: return "FLDZ"; - case I_FMUL: return "FMUL"; + case I_FMUL: return "FMUL"; case I_FMULP: return "FMULP"; case I_FNCLEX: return "FNCLEX"; case I_FNINIT: return "FNINIT"; case I_FNOP: return "FNOP"; - case I_FNSAVE: return "FNSAVE"; + case I_FNSAVE: return "FNSAVE"; case I_FNSTCW: return "FNSTCW"; case I_FNSTENV: return "FNSTENV"; case I_FNSTSW: return "FNSTSW"; case I_FPATAN: return "FPATAN"; - case I_FPREM: return "FPREM"; + case I_FPREM: return "FPREM"; case I_FPREM1: return "FPREM1"; case I_FPTAN: return "FPTAN"; case I_FRNDINT: return "FRNDINT"; case I_FRSTOR: return "FRSTOR"; - case I_FSAVE: return "FSAVE"; + case I_FSAVE: return "FSAVE"; case I_FSCALE: return "FSCALE"; case I_FSETPM: return "FSETPM"; case I_FSIN: return "FSIN"; case I_FSINCOS: return "FSINCOS"; - case I_FSQRT: return "FSQRT"; + case I_FSQRT: return "FSQRT"; case I_FST: return "FST"; case I_FSTCW: return "FSTCW"; case I_FSTENV: return "FSTENV"; case I_FSTP: return "FSTP"; - case I_FSTSW: return "FSTSW"; + case I_FSTSW: return "FSTSW"; case I_FSUB: return "FSUB"; case I_FSUBP: return "FSUBP"; case I_FSUBR: return "FSUBR"; case I_FSUBRP: return "FSUBRP"; - case I_FTST: return "FTST"; + case I_FTST: return "FTST"; case I_FUCOM: return "FUCOM"; case I_FUCOMI: return "FUCOMI"; case I_FUCOMIP: return "FUCOMIP"; case I_FUCOMP: return "FUCOMP"; - case I_FUCOMPP: return "FUCOMPP"; + case I_FUCOMPP: return "FUCOMPP"; case I_FXAM: return "FXAM"; case I_FXCH: return "FXCH"; case I_FXRSTOR: return "FXRSTOR"; case I_FXRSTOR64: return "FXRSTOR64"; - case I_FXSAVE: return "FXSAVE"; + case I_FXSAVE: return "FXSAVE"; case I_FXSAVE64: return "FXSAVE64"; case I_FXTRACT: return "FXTRACT"; case I_FYL2X: return "FYL2X"; case I_FYL2XP1: return "FYL2XP1"; - case I_GETSEC: return "GETSEC"; + case I_GETSEC: return "GETSEC"; case I_HADDPD: return "HADDPD"; case I_HADDPS: return "HADDPS"; case I_HLT: return "HLT"; case I_HSUBPD: return "HSUBPD"; - case I_HSUBPS: return "HSUBPS"; + case I_HSUBPS: return "HSUBPS"; case I_IDIV: return "IDIV"; case I_IMUL: return "IMUL"; case I_IN: return "IN"; case I_INC: return "INC"; case I_INS: return "INS"; - case I_INSERTPS: return "INSERTPS"; + case I_INSERTPS: return "INSERTPS"; case I_INSERTQ: return "INSERTQ"; case I_INT: return "INT"; case I_INT1: return "INT1"; case I_INTO: return "INTO"; - case I_INT_3: return "INT_3"; + case I_INT_3: return "INT_3"; case I_INVD: return "INVD"; case I_INVEPT: return "INVEPT"; case I_INVLPG: return "INVLPG"; case I_INVLPGA: return "INVLPGA"; - case I_INVPCID: return "INVPCID"; + case I_INVPCID: return "INVPCID"; case I_INVVPID: return "INVVPID"; case I_IRET: return "IRET"; case I_JA: return "JA"; case I_JAE: return "JAE"; - case I_JB: return "JB"; + case I_JB: return "JB"; case I_JBE: return "JBE"; case I_JCXZ: return "JCXZ"; case I_JECXZ: return "JECXZ"; case I_JG: return "JG"; case I_JGE: return "JGE"; - case I_JL: return "JL"; + case I_JL: return "JL"; case I_JLE: return "JLE"; case I_JMP: return "JMP"; case I_JMP_FAR: return "JMP_FAR"; case I_JNO: return "JNO"; case I_JNP: return "JNP"; - case I_JNS: return "JNS"; + case I_JNS: return "JNS"; case I_JNZ: return "JNZ"; case I_JO: return "JO"; case I_JP: return "JP"; case I_JRCXZ: return "JRCXZ"; case I_JS: return "JS"; - case I_JZ: return "JZ"; + case I_JZ: return "JZ"; case I_LAHF: return "LAHF"; case I_LAR: return "LAR"; case I_LDDQU: return "LDDQU"; case I_LDMXCSR: return "LDMXCSR"; case I_LDS: return "LDS"; - case I_LEA: return "LEA"; + case I_LEA: return "LEA"; case I_LEAVE: return "LEAVE"; case I_LES: return "LES"; case I_LFENCE: return "LFENCE"; case I_LFS: return "LFS"; case I_LGDT: return "LGDT"; - case I_LGS: return "LGS"; + case I_LGS: return "LGS"; case I_LIDT: return "LIDT"; case I_LLDT: return "LLDT"; case I_LMSW: return "LMSW"; case I_LODS: return "LODS"; case I_LOOP: return "LOOP"; - case I_LOOPNZ: return "LOOPNZ"; + case I_LOOPNZ: return "LOOPNZ"; case I_LOOPZ: return "LOOPZ"; case I_LSL: return "LSL"; case I_LSS: return "LSS"; case I_LTR: return "LTR"; case I_LZCNT: return "LZCNT"; - case I_MASKMOVDQU: return "MASKMOVDQU"; + case I_MASKMOVDQU: return "MASKMOVDQU"; case I_MASKMOVQ: return "MASKMOVQ"; case I_MAXPD: return "MAXPD"; case I_MAXPS: return "MAXPS"; case I_MAXSD: return "MAXSD"; - case I_MAXSS: return "MAXSS"; + case I_MAXSS: return "MAXSS"; case I_MFENCE: return "MFENCE"; case I_MINPD: return "MINPD"; case I_MINPS: return "MINPS"; case I_MINSD: return "MINSD"; - case I_MINSS: return "MINSS"; + case I_MINSS: return "MINSS"; case I_MONITOR: return "MONITOR"; case I_MOV: return "MOV"; case I_MOVAPD: return "MOVAPD"; case I_MOVAPS: return "MOVAPS"; - case I_MOVBE: return "MOVBE"; + case I_MOVBE: return "MOVBE"; case I_MOVD: return "MOVD"; case I_MOVDDUP: return "MOVDDUP"; case I_MOVDQ2Q: return "MOVDQ2Q"; case I_MOVDQA: return "MOVDQA"; - case I_MOVDQU: return "MOVDQU"; + case I_MOVDQU: return "MOVDQU"; case I_MOVHLPS: return "MOVHLPS"; case I_MOVHPD: return "MOVHPD"; case I_MOVHPS: return "MOVHPS"; case I_MOVLHPS: return "MOVLHPS"; - case I_MOVLPD: return "MOVLPD"; + case I_MOVLPD: return "MOVLPD"; case I_MOVLPS: return "MOVLPS"; case I_MOVMSKPD: return "MOVMSKPD"; case I_MOVMSKPS: return "MOVMSKPS"; case I_MOVNTDQ: return "MOVNTDQ"; - case I_MOVNTDQA: return "MOVNTDQA"; + case I_MOVNTDQA: return "MOVNTDQA"; case I_MOVNTI: return "MOVNTI"; case I_MOVNTPD: return "MOVNTPD"; case I_MOVNTPS: return "MOVNTPS"; case I_MOVNTQ: return "MOVNTQ"; - case I_MOVNTSD: return "MOVNTSD"; + case I_MOVNTSD: return "MOVNTSD"; case I_MOVNTSS: return "MOVNTSS"; case I_MOVQ: return "MOVQ"; case I_MOVQ2DQ: return "MOVQ2DQ"; case I_MOVS: return "MOVS"; - case I_MOVSD: return "MOVSD"; + case I_MOVSD: return "MOVSD"; case I_MOVSHDUP: return "MOVSHDUP"; case I_MOVSLDUP: return "MOVSLDUP"; case I_MOVSS: return "MOVSS"; case I_MOVSX: return "MOVSX"; - case I_MOVSXD: return "MOVSXD"; + case I_MOVSXD: return "MOVSXD"; case I_MOVUPD: return "MOVUPD"; case I_MOVUPS: return "MOVUPS"; case I_MOVZX: return "MOVZX"; case I_MPSADBW: return "MPSADBW"; - case I_MUL: return "MUL"; + case I_MUL: return "MUL"; case I_MULPD: return "MULPD"; case I_MULPS: return "MULPS"; case I_MULSD: return "MULSD"; case I_MULSS: return "MULSS"; - case I_MWAIT: return "MWAIT"; + case I_MWAIT: return "MWAIT"; case I_NEG: return "NEG"; case I_NOP: return "NOP"; case I_NOT: return "NOT"; case I_OR: return "OR"; case I_ORPD: return "ORPD"; - case I_ORPS: return "ORPS"; + case I_ORPS: return "ORPS"; case I_OUT: return "OUT"; case I_OUTS: return "OUTS"; case I_PABSB: return "PABSB"; case I_PABSD: return "PABSD"; case I_PABSW: return "PABSW"; - case I_PACKSSDW: return "PACKSSDW"; + case I_PACKSSDW: return "PACKSSDW"; case I_PACKSSWB: return "PACKSSWB"; case I_PACKUSDW: return "PACKUSDW"; case I_PACKUSWB: return "PACKUSWB"; - case I_PADDB: return "PADDB"; + case I_PADDB: return "PADDB"; case I_PADDD: return "PADDD"; case I_PADDQ: return "PADDQ"; case I_PADDSB: return "PADDSB"; case I_PADDSW: return "PADDSW"; - case I_PADDUSB: return "PADDUSB"; + case I_PADDUSB: return "PADDUSB"; case I_PADDUSW: return "PADDUSW"; case I_PADDW: return "PADDW"; case I_PALIGNR: return "PALIGNR"; case I_PAND: return "PAND"; - case I_PANDN: return "PANDN"; + case I_PANDN: return "PANDN"; case I_PAUSE: return "PAUSE"; case I_PAVGB: return "PAVGB"; case I_PAVGUSB: return "PAVGUSB"; case I_PAVGW: return "PAVGW"; - case I_PBLENDVB: return "PBLENDVB"; + case I_PBLENDVB: return "PBLENDVB"; case I_PBLENDW: return "PBLENDW"; case I_PCLMULQDQ: return "PCLMULQDQ"; case I_PCMPEQB: return "PCMPEQB"; - case I_PCMPEQD: return "PCMPEQD"; + case I_PCMPEQD: return "PCMPEQD"; case I_PCMPEQQ: return "PCMPEQQ"; case I_PCMPEQW: return "PCMPEQW"; case I_PCMPESTRI: return "PCMPESTRI"; - case I_PCMPESTRM: return "PCMPESTRM"; + case I_PCMPESTRM: return "PCMPESTRM"; case I_PCMPGTB: return "PCMPGTB"; case I_PCMPGTD: return "PCMPGTD"; case I_PCMPGTQ: return "PCMPGTQ"; - case I_PCMPGTW: return "PCMPGTW"; + case I_PCMPGTW: return "PCMPGTW"; case I_PCMPISTRI: return "PCMPISTRI"; case I_PCMPISTRM: return "PCMPISTRM"; case I_PEXTRB: return "PEXTRB"; - case I_PEXTRD: return "PEXTRD"; + case I_PEXTRD: return "PEXTRD"; case I_PEXTRQ: return "PEXTRQ"; case I_PEXTRW: return "PEXTRW"; case I_PF2ID: return "PF2ID"; case I_PF2IW: return "PF2IW"; - case I_PFACC: return "PFACC"; + case I_PFACC: return "PFACC"; case I_PFADD: return "PFADD"; case I_PFCMPEQ: return "PFCMPEQ"; case I_PFCMPGE: return "PFCMPGE"; case I_PFCMPGT: return "PFCMPGT"; - case I_PFMAX: return "PFMAX"; + case I_PFMAX: return "PFMAX"; case I_PFMIN: return "PFMIN"; case I_PFMUL: return "PFMUL"; case I_PFNACC: return "PFNACC"; case I_PFPNACC: return "PFPNACC"; - case I_PFRCP: return "PFRCP"; + case I_PFRCP: return "PFRCP"; case I_PFRCPIT1: return "PFRCPIT1"; case I_PFRCPIT2: return "PFRCPIT2"; case I_PFRSQIT1: return "PFRSQIT1"; case I_PFRSQRT: return "PFRSQRT"; - case I_PFSUB: return "PFSUB"; + case I_PFSUB: return "PFSUB"; case I_PFSUBR: return "PFSUBR"; case I_PHADDD: return "PHADDD"; case I_PHADDSW: return "PHADDSW"; case I_PHADDW: return "PHADDW"; - case I_PHMINPOSUW: return "PHMINPOSUW"; + case I_PHMINPOSUW: return "PHMINPOSUW"; case I_PHSUBD: return "PHSUBD"; case I_PHSUBSW: return "PHSUBSW"; case I_PHSUBW: return "PHSUBW"; case I_PI2FD: return "PI2FD"; - case I_PI2FW: return "PI2FW"; + case I_PI2FW: return "PI2FW"; case I_PINSRB: return "PINSRB"; case I_PINSRD: return "PINSRD"; case I_PINSRQ: return "PINSRQ"; case I_PINSRW: return "PINSRW"; - case I_PMADDUBSW: return "PMADDUBSW"; + case I_PMADDUBSW: return "PMADDUBSW"; case I_PMADDWD: return "PMADDWD"; case I_PMAXSB: return "PMAXSB"; case I_PMAXSD: return "PMAXSD"; case I_PMAXSW: return "PMAXSW"; - case I_PMAXUB: return "PMAXUB"; + case I_PMAXUB: return "PMAXUB"; case I_PMAXUD: return "PMAXUD"; case I_PMAXUW: return "PMAXUW"; case I_PMINSB: return "PMINSB"; case I_PMINSD: return "PMINSD"; - case I_PMINSW: return "PMINSW"; + case I_PMINSW: return "PMINSW"; case I_PMINUB: return "PMINUB"; case I_PMINUD: return "PMINUD"; case I_PMINUW: return "PMINUW"; case I_PMOVMSKB: return "PMOVMSKB"; - case I_PMOVSXBD: return "PMOVSXBD"; + case I_PMOVSXBD: return "PMOVSXBD"; case I_PMOVSXBQ: return "PMOVSXBQ"; case I_PMOVSXBW: return "PMOVSXBW"; case I_PMOVSXDQ: return "PMOVSXDQ"; - case I_PMOVSXWD: return "PMOVSXWD"; + case I_PMOVSXWD: return "PMOVSXWD"; case I_PMOVSXWQ: return "PMOVSXWQ"; case I_PMOVZXBD: return "PMOVZXBD"; case I_PMOVZXBQ: return "PMOVZXBQ"; - case I_PMOVZXBW: return "PMOVZXBW"; + case I_PMOVZXBW: return "PMOVZXBW"; case I_PMOVZXDQ: return "PMOVZXDQ"; case I_PMOVZXWD: return "PMOVZXWD"; case I_PMOVZXWQ: return "PMOVZXWQ"; - case I_PMULDQ: return "PMULDQ"; + case I_PMULDQ: return "PMULDQ"; case I_PMULHRSW: return "PMULHRSW"; case I_PMULHRW: return "PMULHRW"; case I_PMULHUW: return "PMULHUW"; case I_PMULHW: return "PMULHW"; - case I_PMULLD: return "PMULLD"; + case I_PMULLD: return "PMULLD"; case I_PMULLW: return "PMULLW"; case I_PMULUDQ: return "PMULUDQ"; case I_POP: return "POP"; case I_POPA: return "POPA"; - case I_POPCNT: return "POPCNT"; + case I_POPCNT: return "POPCNT"; case I_POPF: return "POPF"; case I_POR: return "POR"; case I_PREFETCH: return "PREFETCH"; case I_PREFETCHNTA: return "PREFETCHNTA"; - case I_PREFETCHT0: return "PREFETCHT0"; + case I_PREFETCHT0: return "PREFETCHT0"; case I_PREFETCHT1: return "PREFETCHT1"; case I_PREFETCHT2: return "PREFETCHT2"; case I_PREFETCHW: return "PREFETCHW"; - case I_PSADBW: return "PSADBW"; + case I_PSADBW: return "PSADBW"; case I_PSHUFB: return "PSHUFB"; case I_PSHUFD: return "PSHUFD"; case I_PSHUFHW: return "PSHUFHW"; case I_PSHUFLW: return "PSHUFLW"; - case I_PSHUFW: return "PSHUFW"; + case I_PSHUFW: return "PSHUFW"; case I_PSIGNB: return "PSIGNB"; case I_PSIGND: return "PSIGND"; case I_PSIGNW: return "PSIGNW"; case I_PSLLD: return "PSLLD"; - case I_PSLLDQ: return "PSLLDQ"; + case I_PSLLDQ: return "PSLLDQ"; case I_PSLLQ: return "PSLLQ"; case I_PSLLW: return "PSLLW"; case I_PSRAD: return "PSRAD"; case I_PSRAW: return "PSRAW"; - case I_PSRLD: return "PSRLD"; + case I_PSRLD: return "PSRLD"; case I_PSRLDQ: return "PSRLDQ"; case I_PSRLQ: return "PSRLQ"; case I_PSRLW: return "PSRLW"; case I_PSUBB: return "PSUBB"; - case I_PSUBD: return "PSUBD"; + case I_PSUBD: return "PSUBD"; case I_PSUBQ: return "PSUBQ"; case I_PSUBSB: return "PSUBSB"; case I_PSUBSW: return "PSUBSW"; case I_PSUBUSB: return "PSUBUSB"; - case I_PSUBUSW: return "PSUBUSW"; + case I_PSUBUSW: return "PSUBUSW"; case I_PSUBW: return "PSUBW"; case I_PSWAPD: return "PSWAPD"; case I_PTEST: return "PTEST"; case I_PUNPCKHBW: return "PUNPCKHBW"; - case I_PUNPCKHDQ: return "PUNPCKHDQ"; + case I_PUNPCKHDQ: return "PUNPCKHDQ"; case I_PUNPCKHQDQ: return "PUNPCKHQDQ"; case I_PUNPCKHWD: return "PUNPCKHWD"; case I_PUNPCKLBW: return "PUNPCKLBW"; - case I_PUNPCKLDQ: return "PUNPCKLDQ"; + case I_PUNPCKLDQ: return "PUNPCKLDQ"; case I_PUNPCKLQDQ: return "PUNPCKLQDQ"; case I_PUNPCKLWD: return "PUNPCKLWD"; case I_PUSH: return "PUSH"; - case I_PUSHA: return "PUSHA"; + case I_PUSHA: return "PUSHA"; case I_PUSHF: return "PUSHF"; case I_PXOR: return "PXOR"; case I_RCL: return "RCL"; case I_RCPPS: return "RCPPS"; case I_RCPSS: return "RCPSS"; - case I_RCR: return "RCR"; + case I_RCR: return "RCR"; case I_RDFSBASE: return "RDFSBASE"; case I_RDGSBASE: return "RDGSBASE"; case I_RDMSR: return "RDMSR"; case I_RDPMC: return "RDPMC"; - case I_RDRAND: return "RDRAND"; + case I_RDRAND: return "RDRAND"; case I_RDTSC: return "RDTSC"; case I_RDTSCP: return "RDTSCP"; case I_RET: return "RET"; case I_RETF: return "RETF"; - case I_ROL: return "ROL"; + case I_ROL: return "ROL"; case I_ROR: return "ROR"; case I_ROUNDPD: return "ROUNDPD"; case I_ROUNDPS: return "ROUNDPS"; case I_ROUNDSD: return "ROUNDSD"; - case I_ROUNDSS: return "ROUNDSS"; + case I_ROUNDSS: return "ROUNDSS"; case I_RSM: return "RSM"; case I_RSQRTPS: return "RSQRTPS"; case I_RSQRTSS: return "RSQRTSS"; case I_SAHF: return "SAHF"; - case I_SAL: return "SAL"; + case I_SAL: return "SAL"; case I_SALC: return "SALC"; case I_SAR: return "SAR"; case I_SBB: return "SBB"; case I_SCAS: return "SCAS"; case I_SETA: return "SETA"; - case I_SETAE: return "SETAE"; + case I_SETAE: return "SETAE"; case I_SETB: return "SETB"; case I_SETBE: return "SETBE"; case I_SETG: return "SETG"; case I_SETGE: return "SETGE"; case I_SETL: return "SETL"; - case I_SETLE: return "SETLE"; + case I_SETLE: return "SETLE"; case I_SETNO: return "SETNO"; case I_SETNP: return "SETNP"; case I_SETNS: return "SETNS"; case I_SETNZ: return "SETNZ"; - case I_SETO: return "SETO"; + case I_SETO: return "SETO"; case I_SETP: return "SETP"; case I_SETS: return "SETS"; case I_SETZ: return "SETZ"; case I_SFENCE: return "SFENCE"; case I_SGDT: return "SGDT"; - case I_SHL: return "SHL"; + case I_SHL: return "SHL"; case I_SHLD: return "SHLD"; case I_SHR: return "SHR"; case I_SHRD: return "SHRD"; case I_SHUFPD: return "SHUFPD"; case I_SHUFPS: return "SHUFPS"; - case I_SIDT: return "SIDT"; + case I_SIDT: return "SIDT"; case I_SKINIT: return "SKINIT"; case I_SLDT: return "SLDT"; case I_SMSW: return "SMSW"; case I_SQRTPD: return "SQRTPD"; - case I_SQRTPS: return "SQRTPS"; + case I_SQRTPS: return "SQRTPS"; case I_SQRTSD: return "SQRTSD"; case I_SQRTSS: return "SQRTSS"; case I_STC: return "STC"; case I_STD: return "STD"; - case I_STGI: return "STGI"; + case I_STGI: return "STGI"; case I_STI: return "STI"; case I_STMXCSR: return "STMXCSR"; case I_STOS: return "STOS"; case I_STR: return "STR"; case I_SUB: return "SUB"; - case I_SUBPD: return "SUBPD"; + case I_SUBPD: return "SUBPD"; case I_SUBPS: return "SUBPS"; case I_SUBSD: return "SUBSD"; case I_SUBSS: return "SUBSS"; case I_SWAPGS: return "SWAPGS"; - case I_SYSCALL: return "SYSCALL"; + case I_SYSCALL: return "SYSCALL"; case I_SYSENTER: return "SYSENTER"; case I_SYSEXIT: return "SYSEXIT"; case I_SYSRET: return "SYSRET"; case I_TEST: return "TEST"; - case I_TZCNT: return "TZCNT"; + case I_TZCNT: return "TZCNT"; case I_UCOMISD: return "UCOMISD"; case I_UCOMISS: return "UCOMISS"; case I_UD2: return "UD2"; case I_UNDEFINED: return "UNDEFINED"; - case I_UNPCKHPD: return "UNPCKHPD"; + case I_UNPCKHPD: return "UNPCKHPD"; case I_UNPCKHPS: return "UNPCKHPS"; case I_UNPCKLPD: return "UNPCKLPD"; case I_UNPCKLPS: return "UNPCKLPS"; - case I_VADDPD: return "VADDPD"; + case I_VADDPD: return "VADDPD"; case I_VADDPS: return "VADDPS"; case I_VADDSD: return "VADDSD"; case I_VADDSS: return "VADDSS"; case I_VADDSUBPD: return "VADDSUBPD"; - case I_VADDSUBPS: return "VADDSUBPS"; + case I_VADDSUBPS: return "VADDSUBPS"; case I_VAESDEC: return "VAESDEC"; case I_VAESDECLAST: return "VAESDECLAST"; case I_VAESENC: return "VAESENC"; - case I_VAESENCLAST: return "VAESENCLAST"; + case I_VAESENCLAST: return "VAESENCLAST"; case I_VAESIMC: return "VAESIMC"; case I_VAESKEYGENASSIST: return "VAESKEYGENASSIST"; case I_VANDNPD: return "VANDNPD"; - case I_VANDNPS: return "VANDNPS"; + case I_VANDNPS: return "VANDNPS"; case I_VANDPD: return "VANDPD"; case I_VANDPS: return "VANDPS"; case I_VBLENDPD: return "VBLENDPD"; case I_VBLENDPS: return "VBLENDPS"; - case I_VBLENDVPD: return "VBLENDVPD"; + case I_VBLENDVPD: return "VBLENDVPD"; case I_VBLENDVPS: return "VBLENDVPS"; case I_VBROADCASTF128: return "VBROADCASTF128"; case I_VBROADCASTSD: return "VBROADCASTSD"; - case I_VBROADCASTSS: return "VBROADCASTSS"; + case I_VBROADCASTSS: return "VBROADCASTSS"; case I_VCMPEQPD: return "VCMPEQPD"; case I_VCMPEQPS: return "VCMPEQPS"; case I_VCMPEQSD: return "VCMPEQSD"; - case I_VCMPEQSS: return "VCMPEQSS"; + case I_VCMPEQSS: return "VCMPEQSS"; case I_VCMPEQ_OSPD: return "VCMPEQ_OSPD"; case I_VCMPEQ_OSPS: return "VCMPEQ_OSPS"; case I_VCMPEQ_OSSD: return "VCMPEQ_OSSD"; - case I_VCMPEQ_OSSS: return "VCMPEQ_OSSS"; + case I_VCMPEQ_OSSS: return "VCMPEQ_OSSS"; case I_VCMPEQ_UQPD: return "VCMPEQ_UQPD"; case I_VCMPEQ_UQPS: return "VCMPEQ_UQPS"; case I_VCMPEQ_UQSD: return "VCMPEQ_UQSD"; - case I_VCMPEQ_UQSS: return "VCMPEQ_UQSS"; + case I_VCMPEQ_UQSS: return "VCMPEQ_UQSS"; case I_VCMPEQ_USPD: return "VCMPEQ_USPD"; case I_VCMPEQ_USPS: return "VCMPEQ_USPS"; case I_VCMPEQ_USSD: return "VCMPEQ_USSD"; - case I_VCMPEQ_USSS: return "VCMPEQ_USSS"; + case I_VCMPEQ_USSS: return "VCMPEQ_USSS"; case I_VCMPFALSEPD: return "VCMPFALSEPD"; case I_VCMPFALSEPS: return "VCMPFALSEPS"; case I_VCMPFALSESD: return "VCMPFALSESD"; - case I_VCMPFALSESS: return "VCMPFALSESS"; + case I_VCMPFALSESS: return "VCMPFALSESS"; case I_VCMPFALSE_OSPD: return "VCMPFALSE_OSPD"; case I_VCMPFALSE_OSPS: return "VCMPFALSE_OSPS"; - case I_VCMPFALSE_OSSD: return "VCMPFALSE_OSSD"; + case I_VCMPFALSE_OSSD: return "VCMPFALSE_OSSD"; case I_VCMPFALSE_OSSS: return "VCMPFALSE_OSSS"; case I_VCMPGEPD: return "VCMPGEPD"; case I_VCMPGEPS: return "VCMPGEPS"; - case I_VCMPGESD: return "VCMPGESD"; + case I_VCMPGESD: return "VCMPGESD"; case I_VCMPGESS: return "VCMPGESS"; case I_VCMPGE_OQPD: return "VCMPGE_OQPD"; case I_VCMPGE_OQPS: return "VCMPGE_OQPS"; - case I_VCMPGE_OQSD: return "VCMPGE_OQSD"; + case I_VCMPGE_OQSD: return "VCMPGE_OQSD"; case I_VCMPGE_OQSS: return "VCMPGE_OQSS"; case I_VCMPGTPD: return "VCMPGTPD"; case I_VCMPGTPS: return "VCMPGTPS"; - case I_VCMPGTSD: return "VCMPGTSD"; + case I_VCMPGTSD: return "VCMPGTSD"; case I_VCMPGTSS: return "VCMPGTSS"; case I_VCMPGT_OQPD: return "VCMPGT_OQPD"; case I_VCMPGT_OQPS: return "VCMPGT_OQPS"; - case I_VCMPGT_OQSD: return "VCMPGT_OQSD"; + case I_VCMPGT_OQSD: return "VCMPGT_OQSD"; case I_VCMPGT_OQSS: return "VCMPGT_OQSS"; case I_VCMPLEPD: return "VCMPLEPD"; case I_VCMPLEPS: return "VCMPLEPS"; - case I_VCMPLESD: return "VCMPLESD"; + case I_VCMPLESD: return "VCMPLESD"; case I_VCMPLESS: return "VCMPLESS"; case I_VCMPLE_OQPD: return "VCMPLE_OQPD"; case I_VCMPLE_OQPS: return "VCMPLE_OQPS"; - case I_VCMPLE_OQSD: return "VCMPLE_OQSD"; + case I_VCMPLE_OQSD: return "VCMPLE_OQSD"; case I_VCMPLE_OQSS: return "VCMPLE_OQSS"; case I_VCMPLTPD: return "VCMPLTPD"; case I_VCMPLTPS: return "VCMPLTPS"; - case I_VCMPLTSD: return "VCMPLTSD"; + case I_VCMPLTSD: return "VCMPLTSD"; case I_VCMPLTSS: return "VCMPLTSS"; case I_VCMPLT_OQPD: return "VCMPLT_OQPD"; case I_VCMPLT_OQPS: return "VCMPLT_OQPS"; - case I_VCMPLT_OQSD: return "VCMPLT_OQSD"; + case I_VCMPLT_OQSD: return "VCMPLT_OQSD"; case I_VCMPLT_OQSS: return "VCMPLT_OQSS"; case I_VCMPNEQPD: return "VCMPNEQPD"; case I_VCMPNEQPS: return "VCMPNEQPS"; - case I_VCMPNEQSD: return "VCMPNEQSD"; + case I_VCMPNEQSD: return "VCMPNEQSD"; case I_VCMPNEQSS: return "VCMPNEQSS"; case I_VCMPNEQ_OQPD: return "VCMPNEQ_OQPD"; case I_VCMPNEQ_OQPS: return "VCMPNEQ_OQPS"; - case I_VCMPNEQ_OQSD: return "VCMPNEQ_OQSD"; + case I_VCMPNEQ_OQSD: return "VCMPNEQ_OQSD"; case I_VCMPNEQ_OQSS: return "VCMPNEQ_OQSS"; case I_VCMPNEQ_OSPD: return "VCMPNEQ_OSPD"; case I_VCMPNEQ_OSPS: return "VCMPNEQ_OSPS"; - case I_VCMPNEQ_OSSD: return "VCMPNEQ_OSSD"; + case I_VCMPNEQ_OSSD: return "VCMPNEQ_OSSD"; case I_VCMPNEQ_OSSS: return "VCMPNEQ_OSSS"; case I_VCMPNEQ_USPD: return "VCMPNEQ_USPD"; case I_VCMPNEQ_USPS: return "VCMPNEQ_USPS"; - case I_VCMPNEQ_USSD: return "VCMPNEQ_USSD"; + case I_VCMPNEQ_USSD: return "VCMPNEQ_USSD"; case I_VCMPNEQ_USSS: return "VCMPNEQ_USSS"; case I_VCMPNGEPD: return "VCMPNGEPD"; case I_VCMPNGEPS: return "VCMPNGEPS"; - case I_VCMPNGESD: return "VCMPNGESD"; + case I_VCMPNGESD: return "VCMPNGESD"; case I_VCMPNGESS: return "VCMPNGESS"; case I_VCMPNGE_UQPD: return "VCMPNGE_UQPD"; case I_VCMPNGE_UQPS: return "VCMPNGE_UQPS"; - case I_VCMPNGE_UQSD: return "VCMPNGE_UQSD"; + case I_VCMPNGE_UQSD: return "VCMPNGE_UQSD"; case I_VCMPNGE_UQSS: return "VCMPNGE_UQSS"; case I_VCMPNGTPD: return "VCMPNGTPD"; case I_VCMPNGTPS: return "VCMPNGTPS"; - case I_VCMPNGTSD: return "VCMPNGTSD"; + case I_VCMPNGTSD: return "VCMPNGTSD"; case I_VCMPNGTSS: return "VCMPNGTSS"; case I_VCMPNGT_UQPD: return "VCMPNGT_UQPD"; case I_VCMPNGT_UQPS: return "VCMPNGT_UQPS"; - case I_VCMPNGT_UQSD: return "VCMPNGT_UQSD"; + case I_VCMPNGT_UQSD: return "VCMPNGT_UQSD"; case I_VCMPNGT_UQSS: return "VCMPNGT_UQSS"; case I_VCMPNLEPD: return "VCMPNLEPD"; case I_VCMPNLEPS: return "VCMPNLEPS"; - case I_VCMPNLESD: return "VCMPNLESD"; + case I_VCMPNLESD: return "VCMPNLESD"; case I_VCMPNLESS: return "VCMPNLESS"; case I_VCMPNLE_UQPD: return "VCMPNLE_UQPD"; case I_VCMPNLE_UQPS: return "VCMPNLE_UQPS"; - case I_VCMPNLE_UQSD: return "VCMPNLE_UQSD"; + case I_VCMPNLE_UQSD: return "VCMPNLE_UQSD"; case I_VCMPNLE_UQSS: return "VCMPNLE_UQSS"; case I_VCMPNLTPD: return "VCMPNLTPD"; case I_VCMPNLTPS: return "VCMPNLTPS"; - case I_VCMPNLTSD: return "VCMPNLTSD"; + case I_VCMPNLTSD: return "VCMPNLTSD"; case I_VCMPNLTSS: return "VCMPNLTSS"; case I_VCMPNLT_UQPD: return "VCMPNLT_UQPD"; case I_VCMPNLT_UQPS: return "VCMPNLT_UQPS"; - case I_VCMPNLT_UQSD: return "VCMPNLT_UQSD"; + case I_VCMPNLT_UQSD: return "VCMPNLT_UQSD"; case I_VCMPNLT_UQSS: return "VCMPNLT_UQSS"; case I_VCMPORDPD: return "VCMPORDPD"; case I_VCMPORDPS: return "VCMPORDPS"; - case I_VCMPORDSD: return "VCMPORDSD"; + case I_VCMPORDSD: return "VCMPORDSD"; case I_VCMPORDSS: return "VCMPORDSS"; case I_VCMPORD_SPD: return "VCMPORD_SPD"; case I_VCMPORD_SPS: return "VCMPORD_SPS"; - case I_VCMPORD_SSD: return "VCMPORD_SSD"; + case I_VCMPORD_SSD: return "VCMPORD_SSD"; case I_VCMPORD_SSS: return "VCMPORD_SSS"; case I_VCMPTRUEPD: return "VCMPTRUEPD"; case I_VCMPTRUEPS: return "VCMPTRUEPS"; - case I_VCMPTRUESD: return "VCMPTRUESD"; + case I_VCMPTRUESD: return "VCMPTRUESD"; case I_VCMPTRUESS: return "VCMPTRUESS"; case I_VCMPTRUE_USPD: return "VCMPTRUE_USPD"; case I_VCMPTRUE_USPS: return "VCMPTRUE_USPS"; - case I_VCMPTRUE_USSD: return "VCMPTRUE_USSD"; + case I_VCMPTRUE_USSD: return "VCMPTRUE_USSD"; case I_VCMPTRUE_USSS: return "VCMPTRUE_USSS"; case I_VCMPUNORDPD: return "VCMPUNORDPD"; case I_VCMPUNORDPS: return "VCMPUNORDPS"; - case I_VCMPUNORDSD: return "VCMPUNORDSD"; + case I_VCMPUNORDSD: return "VCMPUNORDSD"; case I_VCMPUNORDSS: return "VCMPUNORDSS"; case I_VCMPUNORD_SPD: return "VCMPUNORD_SPD"; case I_VCMPUNORD_SPS: return "VCMPUNORD_SPS"; - case I_VCMPUNORD_SSD: return "VCMPUNORD_SSD"; + case I_VCMPUNORD_SSD: return "VCMPUNORD_SSD"; case I_VCMPUNORD_SSS: return "VCMPUNORD_SSS"; case I_VCOMISD: return "VCOMISD"; case I_VCOMISS: return "VCOMISS"; - case I_VCVTDQ2PD: return "VCVTDQ2PD"; + case I_VCVTDQ2PD: return "VCVTDQ2PD"; case I_VCVTDQ2PS: return "VCVTDQ2PS"; case I_VCVTPD2DQ: return "VCVTPD2DQ"; case I_VCVTPD2PS: return "VCVTPD2PS"; - case I_VCVTPS2DQ: return "VCVTPS2DQ"; + case I_VCVTPS2DQ: return "VCVTPS2DQ"; case I_VCVTPS2PD: return "VCVTPS2PD"; case I_VCVTSD2SI: return "VCVTSD2SI"; case I_VCVTSD2SS: return "VCVTSD2SS"; - case I_VCVTSI2SD: return "VCVTSI2SD"; + case I_VCVTSI2SD: return "VCVTSI2SD"; case I_VCVTSI2SS: return "VCVTSI2SS"; case I_VCVTSS2SD: return "VCVTSS2SD"; case I_VCVTSS2SI: return "VCVTSS2SI"; - case I_VCVTTPD2DQ: return "VCVTTPD2DQ"; + case I_VCVTTPD2DQ: return "VCVTTPD2DQ"; case I_VCVTTPS2DQ: return "VCVTTPS2DQ"; case I_VCVTTSD2SI: return "VCVTTSD2SI"; case I_VCVTTSS2SI: return "VCVTTSS2SI"; - case I_VDIVPD: return "VDIVPD"; + case I_VDIVPD: return "VDIVPD"; case I_VDIVPS: return "VDIVPS"; case I_VDIVSD: return "VDIVSD"; case I_VDIVSS: return "VDIVSS"; case I_VDPPD: return "VDPPD"; - case I_VDPPS: return "VDPPS"; + case I_VDPPS: return "VDPPS"; case I_VERR: return "VERR"; case I_VERW: return "VERW"; case I_VEXTRACTF128: return "VEXTRACTF128"; - case I_VEXTRACTPS: return "VEXTRACTPS"; + case I_VEXTRACTPS: return "VEXTRACTPS"; case I_VFMADD132PD: return "VFMADD132PD"; case I_VFMADD132PS: return "VFMADD132PS"; case I_VFMADD132SD: return "VFMADD132SD"; - case I_VFMADD132SS: return "VFMADD132SS"; + case I_VFMADD132SS: return "VFMADD132SS"; case I_VFMADD213PD: return "VFMADD213PD"; case I_VFMADD213PS: return "VFMADD213PS"; case I_VFMADD213SD: return "VFMADD213SD"; - case I_VFMADD213SS: return "VFMADD213SS"; + case I_VFMADD213SS: return "VFMADD213SS"; case I_VFMADD231PD: return "VFMADD231PD"; case I_VFMADD231PS: return "VFMADD231PS"; case I_VFMADD231SD: return "VFMADD231SD"; - case I_VFMADD231SS: return "VFMADD231SS"; + case I_VFMADD231SS: return "VFMADD231SS"; case I_VFMADDSUB132PD: return "VFMADDSUB132PD"; case I_VFMADDSUB132PS: return "VFMADDSUB132PS"; - case I_VFMADDSUB213PD: return "VFMADDSUB213PD"; + case I_VFMADDSUB213PD: return "VFMADDSUB213PD"; case I_VFMADDSUB213PS: return "VFMADDSUB213PS"; case I_VFMADDSUB231PD: return "VFMADDSUB231PD"; - case I_VFMADDSUB231PS: return "VFMADDSUB231PS"; + case I_VFMADDSUB231PS: return "VFMADDSUB231PS"; case I_VFMSUB132PD: return "VFMSUB132PD"; case I_VFMSUB132PS: return "VFMSUB132PS"; case I_VFMSUB132SD: return "VFMSUB132SD"; - case I_VFMSUB132SS: return "VFMSUB132SS"; + case I_VFMSUB132SS: return "VFMSUB132SS"; case I_VFMSUB213PD: return "VFMSUB213PD"; case I_VFMSUB213PS: return "VFMSUB213PS"; case I_VFMSUB213SD: return "VFMSUB213SD"; - case I_VFMSUB213SS: return "VFMSUB213SS"; + case I_VFMSUB213SS: return "VFMSUB213SS"; case I_VFMSUB231PD: return "VFMSUB231PD"; case I_VFMSUB231PS: return "VFMSUB231PS"; case I_VFMSUB231SD: return "VFMSUB231SD"; - case I_VFMSUB231SS: return "VFMSUB231SS"; + case I_VFMSUB231SS: return "VFMSUB231SS"; case I_VFMSUBADD132PD: return "VFMSUBADD132PD"; case I_VFMSUBADD132PS: return "VFMSUBADD132PS"; - case I_VFMSUBADD213PD: return "VFMSUBADD213PD"; + case I_VFMSUBADD213PD: return "VFMSUBADD213PD"; case I_VFMSUBADD213PS: return "VFMSUBADD213PS"; case I_VFMSUBADD231PD: return "VFMSUBADD231PD"; - case I_VFMSUBADD231PS: return "VFMSUBADD231PS"; + case I_VFMSUBADD231PS: return "VFMSUBADD231PS"; case I_VFNMADD132PD: return "VFNMADD132PD"; case I_VFNMADD132PS: return "VFNMADD132PS"; case I_VFNMADD132SD: return "VFNMADD132SD"; - case I_VFNMADD132SS: return "VFNMADD132SS"; + case I_VFNMADD132SS: return "VFNMADD132SS"; case I_VFNMADD213PD: return "VFNMADD213PD"; case I_VFNMADD213PS: return "VFNMADD213PS"; case I_VFNMADD213SD: return "VFNMADD213SD"; - case I_VFNMADD213SS: return "VFNMADD213SS"; + case I_VFNMADD213SS: return "VFNMADD213SS"; case I_VFNMADD231PD: return "VFNMADD231PD"; case I_VFNMADD231PS: return "VFNMADD231PS"; case I_VFNMADD231SD: return "VFNMADD231SD"; - case I_VFNMADD231SS: return "VFNMADD231SS"; + case I_VFNMADD231SS: return "VFNMADD231SS"; case I_VFNMSUB132PD: return "VFNMSUB132PD"; case I_VFNMSUB132PS: return "VFNMSUB132PS"; case I_VFNMSUB132SD: return "VFNMSUB132SD"; - case I_VFNMSUB132SS: return "VFNMSUB132SS"; + case I_VFNMSUB132SS: return "VFNMSUB132SS"; case I_VFNMSUB213PD: return "VFNMSUB213PD"; case I_VFNMSUB213PS: return "VFNMSUB213PS"; case I_VFNMSUB213SD: return "VFNMSUB213SD"; - case I_VFNMSUB213SS: return "VFNMSUB213SS"; + case I_VFNMSUB213SS: return "VFNMSUB213SS"; case I_VFNMSUB231PD: return "VFNMSUB231PD"; case I_VFNMSUB231PS: return "VFNMSUB231PS"; case I_VFNMSUB231SD: return "VFNMSUB231SD"; - case I_VFNMSUB231SS: return "VFNMSUB231SS"; + case I_VFNMSUB231SS: return "VFNMSUB231SS"; case I_VHADDPD: return "VHADDPD"; case I_VHADDPS: return "VHADDPS"; case I_VHSUBPD: return "VHSUBPD"; case I_VHSUBPS: return "VHSUBPS"; - case I_VINSERTF128: return "VINSERTF128"; + case I_VINSERTF128: return "VINSERTF128"; case I_VINSERTPS: return "VINSERTPS"; case I_VLDDQU: return "VLDDQU"; case I_VLDMXCSR: return "VLDMXCSR"; - case I_VMASKMOVDQU: return "VMASKMOVDQU"; + case I_VMASKMOVDQU: return "VMASKMOVDQU"; case I_VMASKMOVPD: return "VMASKMOVPD"; case I_VMASKMOVPS: return "VMASKMOVPS"; case I_VMAXPD: return "VMAXPD"; - case I_VMAXPS: return "VMAXPS"; + case I_VMAXPS: return "VMAXPS"; case I_VMAXSD: return "VMAXSD"; case I_VMAXSS: return "VMAXSS"; case I_VMCALL: return "VMCALL"; case I_VMCLEAR: return "VMCLEAR"; - case I_VMFUNC: return "VMFUNC"; + case I_VMFUNC: return "VMFUNC"; case I_VMINPD: return "VMINPD"; case I_VMINPS: return "VMINPS"; case I_VMINSD: return "VMINSD"; case I_VMINSS: return "VMINSS"; - case I_VMLAUNCH: return "VMLAUNCH"; + case I_VMLAUNCH: return "VMLAUNCH"; case I_VMLOAD: return "VMLOAD"; case I_VMMCALL: return "VMMCALL"; case I_VMOVAPD: return "VMOVAPD"; case I_VMOVAPS: return "VMOVAPS"; - case I_VMOVD: return "VMOVD"; + case I_VMOVD: return "VMOVD"; case I_VMOVDDUP: return "VMOVDDUP"; case I_VMOVDQA: return "VMOVDQA"; case I_VMOVDQU: return "VMOVDQU"; - case I_VMOVHLPS: return "VMOVHLPS"; + case I_VMOVHLPS: return "VMOVHLPS"; case I_VMOVHPD: return "VMOVHPD"; case I_VMOVHPS: return "VMOVHPS"; case I_VMOVLHPS: return "VMOVLHPS"; case I_VMOVLPD: return "VMOVLPD"; - case I_VMOVLPS: return "VMOVLPS"; + case I_VMOVLPS: return "VMOVLPS"; case I_VMOVMSKPD: return "VMOVMSKPD"; case I_VMOVMSKPS: return "VMOVMSKPS"; case I_VMOVNTDQ: return "VMOVNTDQ"; - case I_VMOVNTDQA: return "VMOVNTDQA"; + case I_VMOVNTDQA: return "VMOVNTDQA"; case I_VMOVNTPD: return "VMOVNTPD"; case I_VMOVNTPS: return "VMOVNTPS"; case I_VMOVQ: return "VMOVQ"; case I_VMOVSD: return "VMOVSD"; - case I_VMOVSHDUP: return "VMOVSHDUP"; + case I_VMOVSHDUP: return "VMOVSHDUP"; case I_VMOVSLDUP: return "VMOVSLDUP"; case I_VMOVSS: return "VMOVSS"; case I_VMOVUPD: return "VMOVUPD"; case I_VMOVUPS: return "VMOVUPS"; - case I_VMPSADBW: return "VMPSADBW"; + case I_VMPSADBW: return "VMPSADBW"; case I_VMPTRLD: return "VMPTRLD"; case I_VMPTRST: return "VMPTRST"; case I_VMREAD: return "VMREAD"; case I_VMRESUME: return "VMRESUME"; - case I_VMRUN: return "VMRUN"; + case I_VMRUN: return "VMRUN"; case I_VMSAVE: return "VMSAVE"; case I_VMULPD: return "VMULPD"; case I_VMULPS: return "VMULPS"; case I_VMULSD: return "VMULSD"; - case I_VMULSS: return "VMULSS"; + case I_VMULSS: return "VMULSS"; case I_VMWRITE: return "VMWRITE"; case I_VMXOFF: return "VMXOFF"; case I_VMXON: return "VMXON"; case I_VORPD: return "VORPD"; - case I_VORPS: return "VORPS"; + case I_VORPS: return "VORPS"; case I_VPABSB: return "VPABSB"; case I_VPABSD: return "VPABSD"; case I_VPABSW: return "VPABSW"; case I_VPACKSSDW: return "VPACKSSDW"; - case I_VPACKSSWB: return "VPACKSSWB"; + case I_VPACKSSWB: return "VPACKSSWB"; case I_VPACKUSDW: return "VPACKUSDW"; case I_VPACKUSWB: return "VPACKUSWB"; case I_VPADDB: return "VPADDB"; - case I_VPADDD: return "VPADDD"; + case I_VPADDD: return "VPADDD"; case I_VPADDQ: return "VPADDQ"; case I_VPADDSB: return "VPADDSB"; case I_VPADDSW: return "VPADDSW"; case I_VPADDUSW: return "VPADDUSW"; - case I_VPADDW: return "VPADDW"; + case I_VPADDW: return "VPADDW"; case I_VPALIGNR: return "VPALIGNR"; case I_VPAND: return "VPAND"; case I_VPANDN: return "VPANDN"; case I_VPAVGB: return "VPAVGB"; - case I_VPAVGW: return "VPAVGW"; + case I_VPAVGW: return "VPAVGW"; case I_VPBLENDVB: return "VPBLENDVB"; case I_VPBLENDW: return "VPBLENDW"; case I_VPCLMULQDQ: return "VPCLMULQDQ"; - case I_VPCMPEQB: return "VPCMPEQB"; + case I_VPCMPEQB: return "VPCMPEQB"; case I_VPCMPEQD: return "VPCMPEQD"; case I_VPCMPEQQ: return "VPCMPEQQ"; case I_VPCMPEQW: return "VPCMPEQW"; - case I_VPCMPESTRI: return "VPCMPESTRI"; + case I_VPCMPESTRI: return "VPCMPESTRI"; case I_VPCMPESTRM: return "VPCMPESTRM"; case I_VPCMPGTB: return "VPCMPGTB"; case I_VPCMPGTD: return "VPCMPGTD"; - case I_VPCMPGTQ: return "VPCMPGTQ"; + case I_VPCMPGTQ: return "VPCMPGTQ"; case I_VPCMPGTW: return "VPCMPGTW"; case I_VPCMPISTRI: return "VPCMPISTRI"; case I_VPCMPISTRM: return "VPCMPISTRM"; - case I_VPERM2F128: return "VPERM2F128"; + case I_VPERM2F128: return "VPERM2F128"; case I_VPERMILPD: return "VPERMILPD"; case I_VPERMILPS: return "VPERMILPS"; case I_VPEXTRB: return "VPEXTRB"; - case I_VPEXTRD: return "VPEXTRD"; + case I_VPEXTRD: return "VPEXTRD"; case I_VPEXTRQ: return "VPEXTRQ"; case I_VPEXTRW: return "VPEXTRW"; case I_VPHADDD: return "VPHADDD"; case I_VPHADDSW: return "VPHADDSW"; - case I_VPHADDW: return "VPHADDW"; + case I_VPHADDW: return "VPHADDW"; case I_VPHMINPOSUW: return "VPHMINPOSUW"; case I_VPHSUBD: return "VPHSUBD"; case I_VPHSUBSW: return "VPHSUBSW"; - case I_VPHSUBW: return "VPHSUBW"; + case I_VPHSUBW: return "VPHSUBW"; case I_VPINSRB: return "VPINSRB"; case I_VPINSRD: return "VPINSRD"; case I_VPINSRQ: return "VPINSRQ"; case I_VPINSRW: return "VPINSRW"; - case I_VPMADDUBSW: return "VPMADDUBSW"; + case I_VPMADDUBSW: return "VPMADDUBSW"; case I_VPMADDWD: return "VPMADDWD"; case I_VPMAXSB: return "VPMAXSB"; case I_VPMAXSD: return "VPMAXSD"; case I_VPMAXSW: return "VPMAXSW"; - case I_VPMAXUB: return "VPMAXUB"; + case I_VPMAXUB: return "VPMAXUB"; case I_VPMAXUD: return "VPMAXUD"; case I_VPMAXUW: return "VPMAXUW"; case I_VPMINSB: return "VPMINSB"; case I_VPMINSD: return "VPMINSD"; - case I_VPMINSW: return "VPMINSW"; + case I_VPMINSW: return "VPMINSW"; case I_VPMINUB: return "VPMINUB"; case I_VPMINUD: return "VPMINUD"; case I_VPMINUW: return "VPMINUW"; - case I_VPMOVMSKB: return "VPMOVMSKB"; + case I_VPMOVMSKB: return "VPMOVMSKB"; case I_VPMOVSXBD: return "VPMOVSXBD"; case I_VPMOVSXBQ: return "VPMOVSXBQ"; case I_VPMOVSXBW: return "VPMOVSXBW"; - case I_VPMOVSXDQ: return "VPMOVSXDQ"; + case I_VPMOVSXDQ: return "VPMOVSXDQ"; case I_VPMOVSXWD: return "VPMOVSXWD"; case I_VPMOVSXWQ: return "VPMOVSXWQ"; case I_VPMOVZXBD: return "VPMOVZXBD"; - case I_VPMOVZXBQ: return "VPMOVZXBQ"; + case I_VPMOVZXBQ: return "VPMOVZXBQ"; case I_VPMOVZXBW: return "VPMOVZXBW"; case I_VPMOVZXDQ: return "VPMOVZXDQ"; case I_VPMOVZXWD: return "VPMOVZXWD"; - case I_VPMOVZXWQ: return "VPMOVZXWQ"; + case I_VPMOVZXWQ: return "VPMOVZXWQ"; case I_VPMULDQ: return "VPMULDQ"; case I_VPMULHRSW: return "VPMULHRSW"; case I_VPMULHUW: return "VPMULHUW"; - case I_VPMULHW: return "VPMULHW"; + case I_VPMULHW: return "VPMULHW"; case I_VPMULLD: return "VPMULLD"; case I_VPMULLW: return "VPMULLW"; case I_VPMULUDQ: return "VPMULUDQ"; case I_VPOR: return "VPOR"; - case I_VPSADBW: return "VPSADBW"; + case I_VPSADBW: return "VPSADBW"; case I_VPSHUFB: return "VPSHUFB"; case I_VPSHUFD: return "VPSHUFD"; case I_VPSHUFHW: return "VPSHUFHW"; - case I_VPSHUFLW: return "VPSHUFLW"; + case I_VPSHUFLW: return "VPSHUFLW"; case I_VPSIGNB: return "VPSIGNB"; case I_VPSIGND: return "VPSIGND"; case I_VPSIGNW: return "VPSIGNW"; case I_VPSLLD: return "VPSLLD"; - case I_VPSLLDQ: return "VPSLLDQ"; + case I_VPSLLDQ: return "VPSLLDQ"; case I_VPSLLQ: return "VPSLLQ"; case I_VPSLLW: return "VPSLLW"; case I_VPSRAD: return "VPSRAD"; case I_VPSRAW: return "VPSRAW"; - case I_VPSRLD: return "VPSRLD"; + case I_VPSRLD: return "VPSRLD"; case I_VPSRLDQ: return "VPSRLDQ"; case I_VPSRLQ: return "VPSRLQ"; case I_VPSRLW: return "VPSRLW"; case I_VPSUBB: return "VPSUBB"; - case I_VPSUBD: return "VPSUBD"; + case I_VPSUBD: return "VPSUBD"; case I_VPSUBQ: return "VPSUBQ"; case I_VPSUBSB: return "VPSUBSB"; case I_VPSUBSW: return "VPSUBSW"; case I_VPSUBUSB: return "VPSUBUSB"; - case I_VPSUBUSW: return "VPSUBUSW"; + case I_VPSUBUSW: return "VPSUBUSW"; case I_VPSUBW: return "VPSUBW"; case I_VPTEST: return "VPTEST"; case I_VPUNPCKHBW: return "VPUNPCKHBW"; - case I_VPUNPCKHDQ: return "VPUNPCKHDQ"; + case I_VPUNPCKHDQ: return "VPUNPCKHDQ"; case I_VPUNPCKHQDQ: return "VPUNPCKHQDQ"; case I_VPUNPCKHWD: return "VPUNPCKHWD"; case I_VPUNPCKLBW: return "VPUNPCKLBW"; - case I_VPUNPCKLDQ: return "VPUNPCKLDQ"; + case I_VPUNPCKLDQ: return "VPUNPCKLDQ"; case I_VPUNPCKLQDQ: return "VPUNPCKLQDQ"; case I_VPUNPCKLWD: return "VPUNPCKLWD"; case I_VPXOR: return "VPXOR"; - case I_VRCPPS: return "VRCPPS"; + case I_VRCPPS: return "VRCPPS"; case I_VRCPSS: return "VRCPSS"; case I_VROUNDPD: return "VROUNDPD"; case I_VROUNDPS: return "VROUNDPS"; - case I_VROUNDSD: return "VROUNDSD"; + case I_VROUNDSD: return "VROUNDSD"; case I_VROUNDSS: return "VROUNDSS"; case I_VRSQRTPS: return "VRSQRTPS"; case I_VRSQRTSS: return "VRSQRTSS"; - case I_VSHUFPD: return "VSHUFPD"; + case I_VSHUFPD: return "VSHUFPD"; case I_VSHUFPS: return "VSHUFPS"; case I_VSQRTPD: return "VSQRTPD"; case I_VSQRTPS: return "VSQRTPS"; case I_VSQRTSD: return "VSQRTSD"; - case I_VSQRTSS: return "VSQRTSS"; + case I_VSQRTSS: return "VSQRTSS"; case I_VSTMXCSR: return "VSTMXCSR"; case I_VSUBPD: return "VSUBPD"; case I_VSUBPS: return "VSUBPS"; case I_VSUBSD: return "VSUBSD"; - case I_VSUBSS: return "VSUBSS"; + case I_VSUBSS: return "VSUBSS"; case I_VTESTPD: return "VTESTPD"; case I_VTESTPS: return "VTESTPS"; case I_VUCOMISD: return "VUCOMISD"; - case I_VUCOMISS: return "VUCOMISS"; + case I_VUCOMISS: return "VUCOMISS"; case I_VUNPCKHPD: return "VUNPCKHPD"; case I_VUNPCKHPS: return "VUNPCKHPS"; case I_VUNPCKLPD: return "VUNPCKLPD"; - case I_VUNPCKLPS: return "VUNPCKLPS"; + case I_VUNPCKLPS: return "VUNPCKLPS"; case I_VXORPD: return "VXORPD"; case I_VXORPS: return "VXORPS"; case I_VZEROALL: return "VZEROALL"; - case I_VZEROUPPER: return "VZEROUPPER"; + case I_VZEROUPPER: return "VZEROUPPER"; case I_WAIT: return "WAIT"; case I_WBINVD: return "WBINVD"; case I_WRFSBASE: return "WRFSBASE"; case I_WRGSBASE: return "WRGSBASE"; - case I_WRMSR: return "WRMSR"; + case I_WRMSR: return "WRMSR"; case I_XABORT: return "XABORT"; case I_XADD: return "XADD"; case I_XBEGIN: return "XBEGIN"; case I_XCHG: return "XCHG"; - case I_XEND: return "XEND"; + case I_XEND: return "XEND"; case I_XGETBV: return "XGETBV"; case I_XLAT: return "XLAT"; case I_XOR: return "XOR"; case I_XORPD: return "XORPD"; - case I_XORPS: return "XORPS"; + case I_XORPS: return "XORPS"; case I_XRSTOR: return "XRSTOR"; case I_XRSTOR64: return "XRSTOR64"; case I_XSAVE: return "XSAVE"; case I_XSAVE64: return "XSAVE64"; - case I_XSAVEOPT: return "XSAVEOPT"; + case I_XSAVEOPT: return "XSAVEOPT"; case I_XSAVEOPT64: return "XSAVEOPT64"; case I_XSETBV: return "XSETBV"; - default: assert(false); return "???"; - } -} - -void output_value(std::stringstream &output, int nibbles, uint32_t value) -{ - if (value < 0xA) - // Show 0 upto 9 as 1 decimal digit - output << std::setw(1) << value; - else - output << std::setfill('0') << std::setw(nibbles) << std::right << value << 'h'; -} - -void output_value_disp(std::stringstream &output, _DInst &info) -{ - uint32_t value = EmuX86_Distorm_read_disp(info); - if (value != 0) { - int nibbles = info.dispSize / 4; - assert(nibbles == 2 || nibbles == 4 || nibbles == 8); - if ((int32_t)value < 0) { - output << '-'; - output_value(output, nibbles, -value); - } - else { - output << '+'; - output_value(output, nibbles, value); - } - } -} - -void output_segment(std::stringstream &output, _DInst &info) -{ - if (SEGMENT_GET(info.segment) != R_NONE) - output << Distorm_RegStrings[SEGMENT_GET(info.segment)] << ":"; -} - -void EmuX86_DistormLogInstruction(const uint8_t *Eip, _DInst &info) -{ - std::stringstream output; - - output << "Disassembly : " - << std::setfill('0') << std::setw(8) << std::right << std::hex << std::uppercase << (xbaddr)Eip; - for (int b = 0; b < MAX(7, info.size); b++) { - if (b < info.size) - //output << " " << std::setfill('0') << std::setw(2) << std::right << std::hex << ((uint8_t)0+Eip[b]); // add 2 hex nibbles, not chars - output << " " << std::setw(2) << ((uint8_t)0+Eip[b]); // add 2 hex nibbles, not chars - else - output << " "; - } - - output << std::setfill(' ') << std::left << std::setw(1) << " "; - if (info.flags & FLAG_LOCK) - output << "LOCK "; - - if (info.flags & FLAG_REPNZ) - output << "REPNZ "; - - if (info.flags & FLAG_REP) { - switch (info.opcode) { - case I_CMPS: - case I_SCAS: - output << "REPZ "; - break; - default: - output << "REP "; - } - } - - output << std::setw(11) << Distorm_OpcodeString(info.opcode); - for (int o = 0; o < 4 && info.ops[o].type != O_NONE; o++) { - // Convert size in bits to (hexadecimal) nibble count and a size-indicator string - int nr_nibbles; - std::string size_str; - - switch (info.ops[o].size) { - case 0: nr_nibbles = 8; size_str = ""; break; - case 8: nr_nibbles = 2; size_str = "byte ptr "; break; - case 16: nr_nibbles = 4; size_str = "word ptr "; break; - case 32: nr_nibbles = 8; size_str = "dword ptr "; break; - default: assert(false); - } - - // Output register/operand separator - output << std::setfill(' ') << std::setw(1) << std::right << ((o == 0) ? " " : ","); - // Render operand to output - switch (info.ops[o].type) { - case O_REG: - output << Distorm_RegStrings[info.ops[o].index]; - break; - case O_IMM: - output_value(output, nr_nibbles, info.imm.dword); - break; - case O_IMM1: // TODO : Needs test-case - output_value(output, nr_nibbles, info.imm.ex.i1); - break; - case O_IMM2: // TODO : Needs test-case - output_value(output, nr_nibbles, info.imm.ex.i2); - break; - case O_DISP: - output << size_str; - output_segment(output, info); // Was << "ds:", so no check on default - output << "["; - output_value(output, info.dispSize > 0 ? info.dispSize / 4 : 8, EmuX86_Distorm_read_disp(info)); - output << "]"; - break; - case O_SMEM: - output << size_str << "["; - if (!SEGMENT_IS_DEFAULT(info.segment)) - output_segment(output, info); - output << Distorm_RegStrings[info.ops[o].index]; - output_value_disp(output, info); - output << "]"; - break; - case O_MEM: - output << size_str << "["; - if (!SEGMENT_IS_DEFAULT(info.segment)) - output_segment(output, info); - if (info.base != R_NONE) - output << Distorm_RegStrings[info.base] << "+"; - output << Distorm_RegStrings[info.ops[o].index]; - if (info.scale >= 2) { - output << "*"; - output_value(output, 1/*nibble*/, info.scale); - } - output_value_disp(output, info); - output << "]"; - break; - case O_PC: - output_value(output, 8, (xbaddr)Eip + (xbaddr)INSTRUCTION_GET_TARGET(&info)); - break; - case O_PTR: // TODO : Needs test-case - output << "+" << std::setfill('0') << info.imm.ptr.seg << "/"; - output_value(output, nr_nibbles, info.imm.ptr.off); - break; - default: - assert(false); - output << "?"; - break; - } - } - - if (FLAG_GET_PRIVILEGED(info.flags)) - output << " // Privileged ring 0 instruction"; - -/* -#define FLAG_LOCK (1 << 0) // The instruction locks memory access. -#define FLAG_REPNZ (1 << 1) // The instruction is prefixed with a REPNZ. -#define FLAG_REP (1 << 2) // The instruction is prefixed with a REP, this can be a REPZ, it depends on the specific instruction. -#define FLAG_HINT_TAKEN (1 << 3) // Indicates there is a hint taken for Jcc instructions only. -#define FLAG_HINT_NOT_TAKEN (1 << 4) // Indicates there is a hint non-taken for Jcc instructions only. -#define FLAG_IMM_SIGNED (1 << 5) // The Imm value is signed extended (E.G in 64 bit decoding mode, a 32 bit imm is usually sign extended into 64 bit imm). -#define FLAG_DST_WR (1 << 6) // The destination operand is writable. -#define FLAG_GET_OPSIZE(flags) (((flags) >> 8) & 3) -#define FLAG_GET_ADDRSIZE(flags) (((flags) >> 10) & 3) -#define FLAG_GET_PREFIX(flags) ((flags) & 7) // To get the LOCK/REPNZ/REP prefixes. -*/ - - EmuLog(LOG_PREFIX, LOG_LEVEL::DEBUG, output.str().c_str()); + default: assert(false); return "???"; + } } - + +void output_value(std::stringstream &output, int nibbles, uint32_t value) +{ + if (value < 0xA) + // Show 0 upto 9 as 1 decimal digit + output << std::setw(1) << value; + else + output << std::setfill('0') << std::setw(nibbles) << std::right << value << 'h'; +} + +void output_value_disp(std::stringstream &output, _DInst &info) +{ + uint32_t value = EmuX86_Distorm_read_disp(info); + if (value != 0) { + int nibbles = info.dispSize / 4; + assert(nibbles == 2 || nibbles == 4 || nibbles == 8); + if ((int32_t)value < 0) { + output << '-'; + output_value(output, nibbles, -value); + } + else { + output << '+'; + output_value(output, nibbles, value); + } + } +} + +void output_segment(std::stringstream &output, _DInst &info) +{ + if (SEGMENT_GET(info.segment) != R_NONE) + output << Distorm_RegStrings[SEGMENT_GET(info.segment)] << ":"; +} + +void EmuX86_DistormLogInstruction(const uint8_t *Eip, _DInst &info) +{ + std::stringstream output; + + output << "Disassembly : " + << std::setfill('0') << std::setw(8) << std::right << std::hex << std::uppercase << (xbaddr)Eip; + for (int b = 0; b < MAX(7, info.size); b++) { + if (b < info.size) + //output << " " << std::setfill('0') << std::setw(2) << std::right << std::hex << ((uint8_t)0+Eip[b]); // add 2 hex nibbles, not chars + output << " " << std::setw(2) << ((uint8_t)0+Eip[b]); // add 2 hex nibbles, not chars + else + output << " "; + } + + output << std::setfill(' ') << std::left << std::setw(1) << " "; + if (info.flags & FLAG_LOCK) + output << "LOCK "; + + if (info.flags & FLAG_REPNZ) + output << "REPNZ "; + + if (info.flags & FLAG_REP) { + switch (info.opcode) { + case I_CMPS: + case I_SCAS: + output << "REPZ "; + break; + default: + output << "REP "; + } + } + + output << std::setw(11) << Distorm_OpcodeString(info.opcode); + for (int o = 0; o < 4 && info.ops[o].type != O_NONE; o++) { + // Convert size in bits to (hexadecimal) nibble count and a size-indicator string + int nr_nibbles; + std::string size_str; + + switch (info.ops[o].size) { + case 0: nr_nibbles = 8; size_str = ""; break; + case 8: nr_nibbles = 2; size_str = "byte ptr "; break; + case 16: nr_nibbles = 4; size_str = "word ptr "; break; + case 32: nr_nibbles = 8; size_str = "dword ptr "; break; + default: assert(false); + } + + // Output register/operand separator + output << std::setfill(' ') << std::setw(1) << std::right << ((o == 0) ? " " : ","); + // Render operand to output + switch (info.ops[o].type) { + case O_REG: + output << Distorm_RegStrings[info.ops[o].index]; + break; + case O_IMM: + output_value(output, nr_nibbles, info.imm.dword); + break; + case O_IMM1: // TODO : Needs test-case + output_value(output, nr_nibbles, info.imm.ex.i1); + break; + case O_IMM2: // TODO : Needs test-case + output_value(output, nr_nibbles, info.imm.ex.i2); + break; + case O_DISP: + output << size_str; + output_segment(output, info); // Was << "ds:", so no check on default + output << "["; + output_value(output, info.dispSize > 0 ? info.dispSize / 4 : 8, EmuX86_Distorm_read_disp(info)); + output << "]"; + break; + case O_SMEM: + output << size_str << "["; + if (!SEGMENT_IS_DEFAULT(info.segment)) + output_segment(output, info); + output << Distorm_RegStrings[info.ops[o].index]; + output_value_disp(output, info); + output << "]"; + break; + case O_MEM: + output << size_str << "["; + if (!SEGMENT_IS_DEFAULT(info.segment)) + output_segment(output, info); + if (info.base != R_NONE) + output << Distorm_RegStrings[info.base] << "+"; + output << Distorm_RegStrings[info.ops[o].index]; + if (info.scale >= 2) { + output << "*"; + output_value(output, 1/*nibble*/, info.scale); + } + output_value_disp(output, info); + output << "]"; + break; + case O_PC: + output_value(output, 8, (xbaddr)Eip + (xbaddr)INSTRUCTION_GET_TARGET(&info)); + break; + case O_PTR: // TODO : Needs test-case + output << "+" << std::setfill('0') << info.imm.ptr.seg << "/"; + output_value(output, nr_nibbles, info.imm.ptr.off); + break; + default: + assert(false); + output << "?"; + break; + } + } + + if (FLAG_GET_PRIVILEGED(info.flags)) + output << " // Privileged ring 0 instruction"; + +/* +#define FLAG_LOCK (1 << 0) // The instruction locks memory access. +#define FLAG_REPNZ (1 << 1) // The instruction is prefixed with a REPNZ. +#define FLAG_REP (1 << 2) // The instruction is prefixed with a REP, this can be a REPZ, it depends on the specific instruction. +#define FLAG_HINT_TAKEN (1 << 3) // Indicates there is a hint taken for Jcc instructions only. +#define FLAG_HINT_NOT_TAKEN (1 << 4) // Indicates there is a hint non-taken for Jcc instructions only. +#define FLAG_IMM_SIGNED (1 << 5) // The Imm value is signed extended (E.G in 64 bit decoding mode, a 32 bit imm is usually sign extended into 64 bit imm). +#define FLAG_DST_WR (1 << 6) // The destination operand is writable. +#define FLAG_GET_OPSIZE(flags) (((flags) >> 8) & 3) +#define FLAG_GET_ADDRSIZE(flags) (((flags) >> 10) & 3) +#define FLAG_GET_PREFIX(flags) ((flags) & 7) // To get the LOCK/REPNZ/REP prefixes. +*/ + + EmuLog(LOG_PREFIX, LOG_LEVEL::DEBUG, output.str().c_str()); +} + int EmuX86_OpcodeSize(uint8_t *Eip) { _DInst info; @@ -2903,13 +2903,13 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) // If an opcode or one of it's operand can't be decoded, that's a clear failure. // However, if for any reason, an opcode operand cannot be read from or written to, // that case may be logged, but it shouldn't fail the opcode handler. - _DInst info; - DWORD StartingEip = e->ContextRecord->Eip; - LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { + _DInst info; + DWORD StartingEip = e->ContextRecord->Eip; + LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { EmuLog(LOG_PREFIX, LOG_LEVEL::DEBUG, "Starting instruction emulation from 0x%08X", e->ContextRecord->Eip); - } - - // Execute op-codes until we hit an unhandled instruction, or an error occurs + } + + // Execute op-codes until we hit an unhandled instruction, or an error occurs while (true) //for (int x=0;x<3;x++) { @@ -2917,28 +2917,28 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "Error decoding opcode at 0x%08X", e->ContextRecord->Eip); assert(false); return false; - } + } - LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { - EmuX86_DistormLogInstruction((uint8_t*)e->ContextRecord->Eip, info); - } - - switch (info.opcode) { // Keep these cases alphabetically ordered and condensed + LOG_CHECK_ENABLED(LOG_LEVEL::DEBUG) { + EmuX86_DistormLogInstruction((uint8_t*)e->ContextRecord->Eip, info); + } + + switch (info.opcode) { // Keep these cases alphabetically ordered and condensed case I_ADD: if (EmuX86_Opcode_ADD(e, info)) break; goto opcode_error; case I_AND: if (EmuX86_Opcode_AND(e, info)) break; - goto opcode_error; - case I_CALL: - // RET and CALL always signify the end of a code block - return true; - case I_CDQ: // = 250 : Convert Doubleword to Quadword - EmuX86_Opcode_CDQ(e, info); - break; - case I_CLI: { // = 502 : Disable all interrupts - EmuX86_Opcode_CLI(); - break; + goto opcode_error; + case I_CALL: + // RET and CALL always signify the end of a code block + return true; + case I_CDQ: // = 250 : Convert Doubleword to Quadword + EmuX86_Opcode_CDQ(e, info); + break; + case I_CLI: { // = 502 : Disable all interrupts + EmuX86_Opcode_CLI(); + break; } case I_CMP: if (EmuX86_Opcode_CMP(e, info)) break; @@ -2955,7 +2955,7 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) #if 0 // TODO : Implement EmuX86_Opcode_IMUL and enable this : case I_IMUL: { // = 117 : Signed Multiply if (EmuX86_Opcode_IMUL(e, info)) break; - goto opcode_error; + goto opcode_error; } #endif case I_IN: @@ -2965,142 +2965,142 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) if (EmuX86_Opcode_INC(e, info)) break; goto opcode_error; case I_INVD: // = 555 : Flush internal caches; initiate flushing of external caches. - break; // Privileged Level (Ring 0) Instruction. Causes a priviledge instruction exception - We can safely ignore this + break; // Privileged Level (Ring 0) Instruction. Causes a priviledge instruction exception - We can safely ignore this case I_INVLPG: { // = 1727 - // This instruction invalidates the TLB entry specified with the source operand. Since we don't emulate - // the TLB yet, we can safely ignore this. Test case: Fable. + // This instruction invalidates the TLB entry specified with the source operand. Since we don't emulate + // the TLB yet, we can safely ignore this. Test case: Fable. break; } - case I_JA: { // = 166 : Jump if above (CF=0 and ZF=0). + case I_JA: { // = 166 : Jump if above (CF=0 and ZF=0). if (EmuX86_Opcode_Jcc(e, info, !EmuX86_HasFlag_CF(e) && !EmuX86_HasFlag_ZF(e))) { continue; - } - break; - } - case I_JAE: { // = 147 : Jump if above or equal (CF=0). + } + break; + } + case I_JAE: { // = 147 : Jump if above or equal (CF=0). if (EmuX86_Opcode_Jcc(e, info, !EmuX86_HasFlag_CF(e))) { continue; - } - break; - } - case I_JB: { // = 143 : Jump if below (CF=1). + } + break; + } + case I_JB: { // = 143 : Jump if below (CF=1). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_CF(e))) { continue; - } - break; - } - case I_JBE: { // = 161 : Jump if below or equal (CF=1 or ZF=1). + } + break; + } + case I_JBE: { // = 161 : Jump if below or equal (CF=1 or ZF=1). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_CF(e) || EmuX86_HasFlag_ZF(e))) { continue; - } - break; - } - case I_JCXZ: { // = 427 : Jump if CX register is 0. + } + break; + } + case I_JCXZ: { // = 427 : Jump if CX register is 0. if (EmuX86_Opcode_Jcc(e, info, ((e->ContextRecord->Ecx & 0xFF) == 0))) { continue; - } - break; - } - case I_JECXZ: { // = 433 : Jump if ECX register is 0. + } + break; + } + case I_JECXZ: { // = 433 : Jump if ECX register is 0. if (EmuX86_Opcode_Jcc(e, info, e->ContextRecord->Ecx == 0)) { continue; - } - break; - } - case I_JG: { // = 202 : Jump if greater (ZF=0 and SF=OF). + } + break; + } + case I_JG: { // = 202 : Jump if greater (ZF=0 and SF=OF). if (EmuX86_Opcode_Jcc(e, info, !EmuX86_HasFlag_ZF(e) && (EmuX86_HasFlag_SF(e) == EmuX86_HasFlag_OF(e)))) { continue; - } - break; - } - case I_JGE: { // = 192 : Jump if greater or equal (SF=OF). + } + break; + } + case I_JGE: { // = 192 : Jump if greater or equal (SF=OF). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_SF(e) == EmuX86_HasFlag_OF(e))) { continue; - } - break; - } - case I_JL: { // = 188 : Jump if less (SF<>OF). + } + break; + } + case I_JL: { // = 188 : Jump if less (SF<>OF). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_SF(e) != EmuX86_HasFlag_OF(e))) { continue; - } - break; - } - case I_JLE: { // = 197 : Jump if less or equal (ZF=1 or SF<>OF). + } + break; + } + case I_JLE: { // = 197 : Jump if less or equal (ZF=1 or SF<>OF). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_ZF(e) || (EmuX86_HasFlag_SF(e) != EmuX86_HasFlag_OF(e)))) { continue; - } - break; - } - case I_JMP: // = 462 : Jump - case I_JMP_FAR: { // = 467 : Jump + } + break; + } + case I_JMP: // = 462 : Jump + case I_JMP_FAR: { // = 467 : Jump if (EmuX86_Opcode_JMP(e, info)) { continue; - } - break; - } - case I_JNO: { // = 138 : Jump if not overflow (OF=0). + } + break; + } + case I_JNO: { // = 138 : Jump if not overflow (OF=0). if (EmuX86_Opcode_Jcc(e, info, !EmuX86_HasFlag_OF(e))) { continue; - } - break; - } - case I_JNP: { // = 183 : Jump if not parity (PF=0). + } + break; + } + case I_JNP: { // = 183 : Jump if not parity (PF=0). if (EmuX86_Opcode_Jcc(e, info, !EmuX86_HasFlag_PF(e))) { continue; - } - break; - } - case I_JNS: { // = 174 : Jump if not sign (SF=0). + } + break; + } + case I_JNS: { // = 174 : Jump if not sign (SF=0). if (EmuX86_Opcode_Jcc(e, info, !EmuX86_HasFlag_SF(e))) { continue; - } - break; - } - case I_JNZ: { // = 156 : Jump if not zero (ZF=0). + } + break; + } + case I_JNZ: { // = 156 : Jump if not zero (ZF=0). if (EmuX86_Opcode_Jcc(e, info, !EmuX86_HasFlag_ZF(e))) { continue; - } - break; - } - case I_JO: { // = 134 : Jump if overflow (OF=1). + } + break; + } + case I_JO: { // = 134 : Jump if overflow (OF=1). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_OF(e))) { continue; - } - break; - } - case I_JP: { // = 179 : Jump if parity (PF=1). + } + break; + } + case I_JP: { // = 179 : Jump if parity (PF=1). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_PF(e))) { continue; - } - break; - } - case I_JS: { // = 170 : Jump if sign (SF=1). + } + break; + } + case I_JS: { // = 170 : Jump if sign (SF=1). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_SF(e))) { continue; - } - break; - } - case I_JZ: { // = 152 : Jump if zero (ZF = 1). + } + break; + } + case I_JZ: { // = 152 : Jump if zero (ZF = 1). if (EmuX86_Opcode_Jcc(e, info, EmuX86_HasFlag_ZF(e))) { continue; - } - break; - } + } + break; + } case I_LEA: { // = 223 : Load Effective Address if (EmuX86_Opcode_LEA(e, info)) break; goto opcode_error; } case I_LEAVE: - // LEAVE often precedes RET - end of a code block + // LEAVE often precedes RET - end of a code block return true; - case I_LFENCE: { // = 4287 : Serializes load operations. - __asm { lfence }; // emulate as-is (doesn't cause exceptions) - break; - } - case I_MFENCE: { // = 4313 : Serializes load and store operations. - __asm { mfence }; // emulate as-is (doesn't cause exceptions) - break; - } + case I_LFENCE: { // = 4287 : Serializes load operations. + __asm { lfence }; // emulate as-is (doesn't cause exceptions) + break; + } + case I_MFENCE: { // = 4313 : Serializes load and store operations. + __asm { mfence }; // emulate as-is (doesn't cause exceptions) + break; + } case I_MOV: if (EmuX86_Opcode_MOV(e, info)) break; goto opcode_error; @@ -3109,8 +3109,8 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) goto opcode_error; case I_MOVZX: if (EmuX86_Opcode_MOVZX(e, info)) break; - goto opcode_error; - case I_NEG: + goto opcode_error; + case I_NEG: if (EmuX86_Opcode_NEG(e, info)) break; goto opcode_error; case I_NOT: @@ -3121,85 +3121,85 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) goto opcode_error; case I_OUT: if (EmuX86_Opcode_OUT(e, info)) break; - goto opcode_error; - case I_POP: { // = 22 : Pop a Value from the Stack + goto opcode_error; + case I_POP: { // = 22 : Pop a Value from the Stack if (EmuX86_Opcode_POP(e, info)) break; goto opcode_error; - } - case I_PUSH: { // = 16 : Push Word or Doubleword Onto the Stack + } + case I_PUSH: { // = 16 : Push Word or Doubleword Onto the Stack if (EmuX86_Opcode_PUSH(e, info)) break; goto opcode_error; } - // TODO : case I_RDPMC: // = 607 : Read Performance-Monitoring Counters; Privileged Level (Ring 0) Instruction. Causes a priviledge instruction exception - case I_RDTSC: // = 593 : Read Time-Stamp Counter - EmuX86_Opcode_RDTSC(e); - break; - case I_RET: - // RET and CALL always signify the end of a code block - return true; - case I_SAR: // = 1002 : Shift arithmetic right - EmuX86_Opcode_SAR(e, info); + // TODO : case I_RDPMC: // = 607 : Read Performance-Monitoring Counters; Privileged Level (Ring 0) Instruction. Causes a priviledge instruction exception + case I_RDTSC: // = 593 : Read Time-Stamp Counter + EmuX86_Opcode_RDTSC(e); + break; + case I_RET: + // RET and CALL always signify the end of a code block + return true; + case I_SAR: // = 1002 : Shift arithmetic right + EmuX86_Opcode_SAR(e, info); break; case I_SBB: if (EmuX86_Opcode_SBB(e, info)) break; - goto opcode_error; - case I_SETA: { // Set byte if above (CF=0 and ZF=0). + goto opcode_error; + case I_SETA: { // Set byte if above (CF=0 and ZF=0). if (EmuX86_Opcode_SETcc(e, info, !EmuX86_HasFlag_CF(e) && !EmuX86_HasFlag_ZF(e))) break; goto opcode_error; } - case I_SETAE: { // Set byte if above or equal (CF=0). + case I_SETAE: { // Set byte if above or equal (CF=0). if (EmuX86_Opcode_SETcc(e, info, !EmuX86_HasFlag_CF(e))) break; goto opcode_error; } - case I_SETB: { // Set byte if below (CF=1). + case I_SETB: { // Set byte if below (CF=1). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_CF(e))) break; goto opcode_error; } - case I_SETBE: { // Set byte if below or equal (CF=1 or ZF=1). + case I_SETBE: { // Set byte if below or equal (CF=1 or ZF=1). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_CF(e) || EmuX86_HasFlag_ZF(e))) break; goto opcode_error; } - case I_SETG: { // Set byte if greater (ZF=0 and SF=OF). + case I_SETG: { // Set byte if greater (ZF=0 and SF=OF). if (EmuX86_Opcode_SETcc(e, info, !EmuX86_HasFlag_ZF(e) && (EmuX86_HasFlag_SF(e) == EmuX86_HasFlag_OF(e)))) break; goto opcode_error; } - case I_SETGE: { // Set byte if greater or equal (SF=OF). + case I_SETGE: { // Set byte if greater or equal (SF=OF). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_SF(e) == EmuX86_HasFlag_OF(e))) break; goto opcode_error; } - case I_SETL: { // Set byte if less (SF<>OF). + case I_SETL: { // Set byte if less (SF<>OF). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_SF(e) != EmuX86_HasFlag_OF(e))) break; goto opcode_error; } - case I_SETLE: { // Set byte if less or equal (ZF=1 or SF<>OF). + case I_SETLE: { // Set byte if less or equal (ZF=1 or SF<>OF). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_ZF(e) || (EmuX86_HasFlag_SF(e) != EmuX86_HasFlag_OF(e)))) break; goto opcode_error; } - case I_SETNO: { // Set byte if not overflow (OF=0). + case I_SETNO: { // Set byte if not overflow (OF=0). if (EmuX86_Opcode_SETcc(e, info, !EmuX86_HasFlag_OF(e))) break; goto opcode_error; } - case I_SETNP: { // Set byte if not parity (PF=0). + case I_SETNP: { // Set byte if not parity (PF=0). if (EmuX86_Opcode_SETcc(e, info, !EmuX86_HasFlag_PF(e))) break; goto opcode_error; } - case I_SETNS: { // Set byte if not sign (SF=0). + case I_SETNS: { // Set byte if not sign (SF=0). if (EmuX86_Opcode_SETcc(e, info, !EmuX86_HasFlag_SF(e))) break; goto opcode_error; } - case I_SETNZ: { // Set byte if not zero (ZF=0). + case I_SETNZ: { // Set byte if not zero (ZF=0). if (EmuX86_Opcode_SETcc(e, info, !EmuX86_HasFlag_ZF(e))) break; goto opcode_error; } - case I_SETO: { // Set byte if overflow (OF=1). + case I_SETO: { // Set byte if overflow (OF=1). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_OF(e))) break; goto opcode_error; } - case I_SETP: { // Set byte if parity (PF=1). + case I_SETP: { // Set byte if parity (PF=1). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_PF(e))) break; goto opcode_error; } - case I_SETS: { // Set byte if sign (SF=1). + case I_SETS: { // Set byte if sign (SF=1). if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_SF(e))) break; goto opcode_error; } @@ -3207,27 +3207,27 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) if (EmuX86_Opcode_SETcc(e, info, EmuX86_HasFlag_ZF(e))) break; goto opcode_error; } - case I_SFENCE: { // = 4343 : Serializes store operations. - __asm { sfence }; // emulate as-is (doesn't cause exceptions) - break; - } + case I_SFENCE: { // = 4343 : Serializes store operations. + __asm { sfence }; // emulate as-is (doesn't cause exceptions) + break; + } case I_SHL: if (EmuX86_Opcode_SHL(e, info)) break; goto opcode_error; case I_SHR: if (EmuX86_Opcode_SHR(e, info)) break; goto opcode_error; - case I_STI: { - // Enable all interrupts - EmuX86_Opcode_STI(); - break; - } + case I_STI: { + // Enable all interrupts + EmuX86_Opcode_STI(); + break; + } case I_SUB: if (EmuX86_Opcode_SUB(e, info)) break; goto opcode_error; case I_TEST: if (EmuX86_Opcode_TEST(e, info)) break; - goto opcode_error; + goto opcode_error; case I_WBINVD: // Write back and flush internal caches; initiate writing-back and flushing of external caches. break; // Privileged Level (Ring 0) Instruction. Causes a priviledge instruction exception - We can safely ignore this case I_WRMSR: @@ -3236,34 +3236,34 @@ bool EmuX86_DecodeException(LPEXCEPTION_POINTERS e) // This needs fixing eventually, but should be acceptible to ignore for now! // Chase: Hollywood Stunt Driver hits this EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "WRMSR instruction ignored"); - break; + break; case I_XOR: if (EmuX86_Opcode_XOR(e, info)) break; goto opcode_error; default: - EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "Unhandled instruction : %s (%u)", Distorm_OpcodeString(info.opcode), info.opcode); - // Fail if the first hit instruction couldn't be emulated, - // but let host CPU execute following (unhandled) instructions : - return (StartingEip != e->ContextRecord->Eip); - } // switch info.opcode - - e->ContextRecord->Eip += info.size; + EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "Unhandled instruction : %s (%u)", Distorm_OpcodeString(info.opcode), info.opcode); + // Fail if the first hit instruction couldn't be emulated, + // but let host CPU execute following (unhandled) instructions : + return (StartingEip != e->ContextRecord->Eip); + } // switch info.opcode + + e->ContextRecord->Eip += info.size; } // while true return true; opcode_error: - EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "0x%08X: Error while handling instruction %s (%u)", e->ContextRecord->Eip, Distorm_OpcodeString(info.opcode), info.opcode); - assert(false); + EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "0x%08X: Error while handling instruction %s (%u)", e->ContextRecord->Eip, Distorm_OpcodeString(info.opcode), info.opcode); + assert(false); return false; } void EmuX86_Init() -{ +{ DBG_PRINTF("Initializing distorm version %d\n", distorm_version()); AddVectoredExceptionHandler(/*FirstHandler=*/ULONG(true), lleException); - EmuX86_InitContextRecordOffsetByRegisterType(); + EmuX86_InitContextRecordOffsetByRegisterType(); EmuX86_InitMemoryBackedRegisters(); } diff --git a/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp b/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp index 87975ec75..089fbd8ff 100644 --- a/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp +++ b/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp @@ -3439,12 +3439,14 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) DWORD *pRecompiledDeclaration = NULL; DWORD *pRecompiledFunction = NULL; DWORD VertexShaderSize = 0; - DWORD DeclarationSize = 0; + DWORD OriginalDeclarationSize = 0; + DWORD HostDeclarationSize = 0; DWORD Handle = 0; HRESULT hRet = XTL::EmuRecompileVshDeclaration((DWORD*)pDeclaration, (XTL::D3DVERTEXELEMENT9**)&pRecompiledDeclaration, - &DeclarationSize, + &OriginalDeclarationSize, + &HostDeclarationSize, pFunction == NULL, &pVertexShader->VertexShaderInfo); @@ -3470,7 +3472,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) g_VertexShaderConstantMode == X_D3DSCM_NORESERVEDCONSTANTS, &bUseDeclarationOnly, pRecompiledDeclaration, - DeclarationSize); + HostDeclarationSize); if (SUCCEEDED(hRet)) { if (!bUseDeclarationOnly) @@ -3540,14 +3542,15 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader) free(pRecompiledDeclaration); - pVertexShader->pDeclaration = (DWORD*)g_VMManager.Allocate(DeclarationSize); - memcpy(pVertexShader->pDeclaration, pDeclaration, DeclarationSize); + pVertexShader->pDeclaration = (DWORD*)g_VMManager.Allocate(HostDeclarationSize); + memcpy(pVertexShader->pDeclaration, pDeclaration, HostDeclarationSize); pVertexShader->FunctionSize = 0; pVertexShader->pFunction = NULL; pVertexShader->Type = X_VST_NORMAL; pVertexShader->Size = (VertexShaderSize - sizeof(VSH_SHADER_HEADER)) / VSH_INSTRUCTION_SIZE_BYTES; - pVertexShader->DeclarationSize = DeclarationSize; + pVertexShader->OriginalDeclarationSize = OriginalDeclarationSize; + pVertexShader->HostDeclarationSize = HostDeclarationSize; if(SUCCEEDED(hRet)) { @@ -5549,7 +5552,18 @@ VOID __stdcall XTL::EMUPATCH(D3DDevice_SetTextureState_TexCoordIndex_0) mov Value, eax } - return EMUPATCH(D3DDevice_SetTextureState_TexCoordIndex)(Stage, Value); + LOG_FUNC_BEGIN + LOG_FUNC_ARG(Stage) + LOG_FUNC_ARG(Value) + LOG_FUNC_END; + + if (Value >= 0x00040000) { + EmuLog(LOG_PREFIX, LOG_LEVEL::WARNING, "EmuD3DDevice_SetTextureState_TexCoordIndex: Unknown TexCoordIndex Value (0x%.08X)", Value); + return; + } + + HRESULT hRet = g_pD3DDevice->SetTextureStageState(Stage, D3DTSS_TEXCOORDINDEX, Value); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetTextureStageState"); } // This uses a custom calling convention where parameter is passed in ESI @@ -5595,6 +5609,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_TexCoordIndex) LOG_FUNC_ARG(Value) LOG_FUNC_END; + XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_TexCoordIndex, (DWORD, DWORD)); + XB_D3DDevice_SetTextureState_TexCoordIndex(Stage, Value); + // TODO: Xbox Direct3D supports sphere mapping OpenGL style. // BUG FIX: The lower 16 bits were causing false Unknown TexCoordIndex errors. @@ -5619,6 +5636,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_TwoSidedLighting) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_TwoSidedLighting, (DWORD)); + XB_D3DDevice_SetRenderState_TwoSidedLighting(Value); + LOG_NOT_SUPPORTED(); } @@ -5642,6 +5662,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_BackFillMode) // of Direct3D was specifically created to take advantage of certain NVIDIA // GPU registers and provide more OpenGL-like features IHMO. LOG_NOT_SUPPORTED(); + + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_BackFillMode, (DWORD)); + XB_D3DDevice_SetRenderState_BackFillMode(Value); } // LTCG specific D3DDevice_SetTextureState_BorderColor function... @@ -5659,6 +5682,7 @@ VOID XTL::EMUPATCH(D3DDevice_SetTextureState_BorderColor_0) mov Value, ebx } + return EMUPATCH(D3DDevice_SetTextureState_BorderColor)(Stage, Value); } @@ -5698,6 +5722,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_BorderColor) LOG_FUNC_ARG(Value) LOG_FUNC_END; + XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_BorderColor, (DWORD, DWORD)); + XB_D3DDevice_SetTextureState_BorderColor(Stage, Value); + HRESULT hRet; hRet = g_pD3DDevice->SetSamplerState(Stage, D3DSAMP_BORDERCOLOR, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetTextureStageState"); @@ -5718,7 +5745,7 @@ VOID XTL::EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor_0) mov Value, ebx } - return EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor)(Stage, Value); + LOG_NOT_SUPPORTED(); } // This uses a custom calling convention where parameter is passed in EAX @@ -5731,7 +5758,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor_4) DWORD Stage; __asm mov Stage, eax; - return EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor)(Stage, Value); + LOG_NOT_SUPPORTED(); } // ****************************************************************** @@ -5748,6 +5775,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_ColorKeyColor) LOG_FUNC_ARG(Value) LOG_FUNC_END; + XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_ColorKeyColor, (DWORD, DWORD)); + XB_D3DDevice_SetTextureState_ColorKeyColor(Stage, Value); + LOG_NOT_SUPPORTED(); } @@ -5814,6 +5844,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetTextureState_BumpEnv) LOG_FUNC_ARG(Value) LOG_FUNC_END; + XB_trampoline(VOID, WINAPI, D3DDevice_SetTextureState_BumpEnv, (DWORD, X_D3DTEXTURESTAGESTATETYPE, DWORD)); + XB_D3DDevice_SetTextureState_BumpEnv(Stage, Type, Value); + HRESULT hRet = D3D_OK; switch(Type) @@ -5851,6 +5884,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_FrontFace) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_FrontFace, (DWORD)); + XB_D3DDevice_SetRenderState_FrontFace(Value); + LOG_NOT_SUPPORTED(); } @@ -5864,6 +5900,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_LogicOp) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_LogicOp, (DWORD)); + XB_D3DDevice_SetRenderState_LogicOp(Value); + LOG_NOT_SUPPORTED(); } @@ -5877,6 +5916,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_NormalizeNormals) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_NormalizeNormals, (DWORD)); + XB_D3DDevice_SetRenderState_NormalizeNormals(Value); + HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } @@ -5891,6 +5933,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_TextureFactor) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_TextureFactor, (DWORD)); + XB_D3DDevice_SetRenderState_TextureFactor(Value); + HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_TEXTUREFACTOR, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } @@ -5907,6 +5952,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_ZBias) HRESULT hRet; + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_ZBias, (DWORD)); + XB_D3DDevice_SetRenderState_ZBias(Value); + FLOAT Biased = static_cast(Value) * -0.000005f; Value = *reinterpret_cast(&Biased); @@ -5924,6 +5972,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_EdgeAntiAlias) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_EdgeAntiAlias, (DWORD)); + XB_D3DDevice_SetRenderState_EdgeAntiAlias(Value); + // TODO: Analyze performance and compatibility (undefined behavior on PC with triangles or points) // HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_EDGEANTIALIAS, Value); // DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); @@ -5941,6 +5992,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_FillMode) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_FillMode, (DWORD)); + XB_D3DDevice_SetRenderState_FillMode(Value); + DWORD dwFillMode; if(Value != 0) @@ -5967,6 +6021,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_FogColor) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_FogColor, (DWORD)); + XB_D3DDevice_SetRenderState_FogColor(Value); + HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_FOGCOLOR, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } @@ -5981,6 +6038,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_Dxt1NoiseEnable) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_Dxt1NoiseEnable, (DWORD)); + XB_D3DDevice_SetRenderState_Dxt1NoiseEnable(Value); + LOG_UNIMPLEMENTED(); } @@ -5998,6 +6058,9 @@ VOID __fastcall XTL::EMUPATCH(D3DDevice_SetRenderState_Simple) LOG_FUNC_ARG(Value) LOG_FUNC_END; + XB_trampoline(VOID, __fastcall, D3DDevice_SetRenderState_Simple, (DWORD, DWORD)); + XB_D3DDevice_SetRenderState_Simple(Method, Value); + // Special Case: Handle PixelShader related Render States // TODO: Port over EmuMappedD3DRenderState and related code from Dxbx or Wip_LessVertexPatching // After this, we don't need to do this part anymore @@ -6207,6 +6270,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_VertexBlend) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_VertexBlend, (DWORD)); + XB_D3DDevice_SetRenderState_VertexBlend(Value); + // convert from Xbox direct3d to PC direct3d enumeration if(Value <= 1) { Value = Value; @@ -6233,6 +6299,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_PSTextureModes) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_PSTextureModes, (DWORD)); + XB_D3DDevice_SetRenderState_PSTextureModes(Value); + XTL::TemporaryPixelShaderRenderStates[XTL::X_D3DRS_PSTEXTUREMODES] = Value; } @@ -6246,6 +6315,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_CullMode) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_CullMode, (DWORD)); + XB_D3DDevice_SetRenderState_CullMode(Value); + // convert from Xbox D3D to PC D3D enumeration // TODO: XDK-Specific Tables? So far they are the same switch(Value) @@ -6277,6 +6349,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_LineWidth) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_LineWidth, (DWORD)); + XB_D3DDevice_SetRenderState_LineWidth(Value); + // TODO: Convert to PC format?? // g_pD3DDevice->SetRenderState(D3DRS_LINEPATTERN, Value); LOG_NOT_SUPPORTED(); @@ -6292,6 +6367,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_StencilFail) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_StencilFail, (DWORD)); + XB_D3DDevice_SetRenderState_StencilFail(Value); + HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_STENCILFAIL, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } @@ -6306,6 +6384,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_OcclusionCullEnable) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_OcclusionCullEnable, (DWORD)); + XB_D3DDevice_SetRenderState_OcclusionCullEnable(Value); + LOG_NOT_SUPPORTED(); } @@ -6319,6 +6400,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_StencilCullEnable) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_StencilCullEnable, (DWORD)); + XB_D3DDevice_SetRenderState_StencilCullEnable(Value); + LOG_NOT_SUPPORTED(); } @@ -6332,6 +6416,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_RopZCmpAlwaysRead) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_RopZCmpAlwaysRead, (DWORD)); + XB_D3DDevice_SetRenderState_RopZCmpAlwaysRead(Value); + LOG_NOT_SUPPORTED(); } @@ -6345,6 +6432,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_RopZRead) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_RopZRead, (DWORD)); + XB_D3DDevice_SetRenderState_RopZRead(Value); + LOG_NOT_SUPPORTED(); } @@ -6358,6 +6448,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_DoNotCullUncompressed) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_DoNotCullUncompressed, (DWORD)); + XB_D3DDevice_SetRenderState_DoNotCullUncompressed(Value); + LOG_NOT_SUPPORTED(); } @@ -6388,6 +6481,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_StencilEnable) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_StencilEnable, (DWORD)); + XB_D3DDevice_SetRenderState_StencilEnable(Value); + HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_STENCILENABLE, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } @@ -6402,6 +6498,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleAntiAlias) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleAntiAlias, (DWORD)); + XB_D3DDevice_SetRenderState_MultiSampleAntiAlias(Value); + HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } @@ -6416,6 +6515,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleMask) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleMask, (DWORD)); + XB_D3DDevice_SetRenderState_MultiSampleMask(Value); + HRESULT hRet = g_pD3DDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, Value); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetRenderState"); } @@ -6430,6 +6532,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleMode) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleMode, (DWORD)); + XB_D3DDevice_SetRenderState_MultiSampleMode(Value); + LOG_NOT_SUPPORTED(); } @@ -6443,6 +6548,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_MultiSampleRenderTargetMode) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_MultiSampleRenderTargetMode, (DWORD)); + XB_D3DDevice_SetRenderState_MultiSampleRenderTargetMode(Value); + LOG_NOT_SUPPORTED(); } @@ -6456,6 +6564,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_ShadowFunc) { LOG_FUNC_ONE_ARG(Value); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_ShadowFunc, (DWORD)); + XB_D3DDevice_SetRenderState_ShadowFunc(Value); + // ShadowFunc reflects the following Xbox-only extension // // typedef enum _D3DRENDERSTATETYPE { @@ -7561,24 +7672,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DrawIndexedVerticesUP) } } -// ****************************************************************** -// * patch: D3DDevice_GetLight -// ****************************************************************** -VOID WINAPI XTL::EMUPATCH(D3DDevice_GetLight) -( - DWORD Index, - X_D3DLIGHT8 *pLight -) -{ - LOG_FUNC_BEGIN - LOG_FUNC_ARG(Index) - LOG_FUNC_ARG(pLight) - LOG_FUNC_END; - - HRESULT hRet = g_pD3DDevice->GetLight(Index, pLight); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetLight"); -} - // ****************************************************************** // * patch: D3DDevice_SetLight // ****************************************************************** @@ -7593,6 +7686,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_SetLight) LOG_FUNC_ARG(pLight) LOG_FUNC_END; + XB_trampoline(HRESULT, WINAPI, D3DDevice_SetLight, (DWORD, CONST X_D3DLIGHT8*)); + XB_D3DDevice_SetLight(Index, pLight); + HRESULT hRet = g_pD3DDevice->SetLight(Index, pLight); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetLight"); @@ -7627,6 +7723,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_LightEnable) LOG_FUNC_ARG(bEnable) LOG_FUNC_END; + XB_trampoline(HRESULT, WINAPI, D3DDevice_LightEnable, (DWORD, BOOL)); + XB_D3DDevice_LightEnable(Index, bEnable); + HRESULT hRet = g_pD3DDevice->LightEnable(Index, bEnable); DEBUG_D3DRESULT(hRet, "g_pD3DDevice->LightEnable"); @@ -8243,9 +8342,9 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_LoadVertexShaderProgram) { DWORD hNewShader = 0; - // Save the contents of the existing vertex shader programLOG_TEST_CASE(LOG_PREFIX, - DWORD* pDeclaration = (DWORD*) malloc( pVertexShader->DeclarationSize ); - memmove( pDeclaration, pVertexShader->pDeclaration, pVertexShader->DeclarationSize ); + // Save the contents of the existing vertex shader program + DWORD* pDeclaration = (DWORD*) malloc( pVertexShader->OriginalDeclarationSize ); + memmove( pDeclaration, pVertexShader->pDeclaration, pVertexShader->OriginalDeclarationSize); // Create a new vertex shader with the new HRESULT hr = EMUPATCH(D3DDevice_CreateVertexShader)( pDeclaration, pFunction, &hNewShader, 0 ); @@ -8319,12 +8418,13 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderDeclaration) if (pSizeOfData) { CxbxVertexShader *pVertexShader = MapXboxVertexShaderHandleToCxbxVertexShader(Handle); if (pVertexShader) { - if (*pSizeOfData < pVertexShader->DeclarationSize || !pData) { - *pSizeOfData = pVertexShader->DeclarationSize; + DWORD sizeOfData = pVertexShader->OriginalDeclarationSize * sizeof(DWORD); + if (*pSizeOfData < sizeOfData || !pData) { + *pSizeOfData = sizeOfData; hRet = !pData ? D3D_OK : D3DERR_MOREDATA; } else { - memcpy(pData, pVertexShader->pDeclaration, pVertexShader->DeclarationSize); + memcpy(pData, pVertexShader->pDeclaration, pVertexShader->OriginalDeclarationSize); hRet = D3D_OK; } } @@ -8756,6 +8856,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_SampleAlpha) { LOG_FUNC_ONE_ARG(dwSampleAlpha); + XB_trampoline(VOID, WINAPI, D3DDevice_SetRenderState_SampleAlpha, (DWORD)); + XB_D3DDevice_SetRenderState_SampleAlpha(dwSampleAlpha); + // TODO: Implement? LOG_UNIMPLEMENTED(); diff --git a/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp.unused-patches b/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp.unused-patches index f595f729e..ceb50d473 100644 --- a/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp.unused-patches +++ b/src/core/HLE/D3D8/Direct3D9/Direct3D9.cpp.unused-patches @@ -2811,207 +2811,225 @@ VOID __fastcall XTL::EMUPATCH(D3DDevice_SetRenderState_Deferred) } - -// ****************************************************************** -// * patch: D3DDevice_GetViewport -// ****************************************************************** -VOID WINAPI XTL::EMUPATCH(D3DDevice_GetViewport) -( - X_D3DVIEWPORT8 *pViewport -) -{ - FUNC_EXPORTS - - LOG_FUNC_ONE_ARG(pViewport); - - D3DVIEWPORT HostViewPort; - - HRESULT hRet = g_pD3DDevice->GetViewport(&HostViewPort); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport"); - - if (!g_ScaleViewport) { - *pViewport = HostViewPort; - } - else { - // Note : We cannot return the Xbox viewport as set in EMUPATCH(D3DDevice_SetViewport) - // because various Xbox D3D functions reset the Xbox viewport. Since we call comparable - // functions on host D3D, the host viewport is better suited as a return value; - // We just need to scale the host viewport back to Xbox dimensions - the exact opposite - // operation from the up-scaling that happens in EMUPATCH(D3DDevice_SetViewport). - - // Get current host render target dimensions - DWORD HostRenderTarget_Width; - DWORD HostRenderTarget_Height; - - if (GetHostRenderTargetDimensions(&HostRenderTarget_Width, &HostRenderTarget_Height)) { - - // Get current Xbox render target dimensions - DWORD XboxRenderTarget_Width = GetPixelContainerWidth(g_pXboxRenderTarget); - DWORD XboxRenderTarget_Height = GetPixelContainerHeigth(g_pXboxRenderTarget); - - // Scale host back to Xbox dimensions (avoiding hard-coding 640 x 480) - pViewport->X = ScaleDWORD(HostViewPort.X, HostRenderTarget_Width, XboxRenderTarget_Width); - pViewport->Y = ScaleDWORD(HostViewPort.Y, HostRenderTarget_Height, XboxRenderTarget_Height); - pViewport->Width = ScaleDWORD(HostViewPort.Width, HostRenderTarget_Width, XboxRenderTarget_Width); - pViewport->Height = ScaleDWORD(HostViewPort.Height, HostRenderTarget_Height, XboxRenderTarget_Height); - pViewport->MinZ = HostViewPort.MinZ; // No need scale Z for now - pViewport->MaxZ = HostViewPort.MaxZ; - } - else { - *pViewport = HostViewPort; - EmuWarning("GetHostRenderTargetDimensions failed - GetViewport returns host viewport instead!"); - } - } -} - -// ****************************************************************** -// * patch: D3D_BlockOnResource -// ****************************************************************** -void WINAPI XTL::EMUPATCH(D3D_BlockOnResource)( X_D3DResource* pResource ) -{ - FUNC_EXPORTS - - LOG_FUNC_ONE_ARG(pResource); - - // TODO: Implement - // NOTE: Azurik appears to call this directly from numerous points - LOG_UNIMPLEMENTED(); - -} - - -// ****************************************************************** -// * patch: IDirect3DResource8_IsBusy -// ****************************************************************** -BOOL WINAPI XTL::EMUPATCH(D3DResource_IsBusy) -( - X_D3DResource *pThis -) -{ - FUNC_EXPORTS - - /* too much output - LOG_FUNC_ONE_ARG(pThis); - //*/ - - return FALSE; -} - - -// ****************************************************************** -// * patch: D3DDevice_SetScissors -// ****************************************************************** -VOID WINAPI XTL::EMUPATCH(D3DDevice_SetScissors) -( - DWORD Count, - BOOL Exclusive, - CONST D3DRECT *pRects -) -{ - FUNC_EXPORTS - - LOG_FUNC_BEGIN - LOG_FUNC_ARG(Count) - LOG_FUNC_ARG(Exclusive) - LOG_FUNC_ARG(pRects) - LOG_FUNC_END; - - // TODO: Implement - LOG_UNIMPLEMENTED(); -} - -// ****************************************************************** -// * patch: D3DDevice_GetScissors -// ****************************************************************** -VOID WINAPI XTL::EMUPATCH(D3DDevice_GetScissors) -( - DWORD *pCount, - BOOL *pExclusive, - D3DRECT *pRects -) -{ - FUNC_EXPORTS - - LOG_FUNC_BEGIN - LOG_FUNC_ARG(pCount) - LOG_FUNC_ARG(pExclusive) - LOG_FUNC_ARG(pRects) - LOG_FUNC_END; - - // TODO: Save a copy of each scissor rect in case this function is called - // in conjunction with D3DDevice::SetScissors. So far, only Outrun2 uses - // this function. For now, just return the values within the current - // viewport. - - D3DVIEWPORT vp; - - HRESULT hRet = g_pD3DDevice->GetViewport( &vp ); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport"); - - pRects->x1 = pRects->y1 = 0; - pRects->x2 = vp.Width; - pRects->y2 = vp.Height; - - pExclusive[0] = FALSE; -} - - -// ****************************************************************** -// * patch: D3DDevice_SetBackMaterial -// ****************************************************************** -VOID WINAPI XTL::EMUPATCH(D3DDevice_SetBackMaterial) -( - X_D3DMATERIAL8* pMaterial -) -{ - FUNC_EXPORTS - - LOG_FUNC_ONE_ARG(pMaterial); - - LOG_NOT_SUPPORTED(); -} - - - -// ****************************************************************** -// * patch: D3DDevice_GetBackMaterial -// ****************************************************************** -VOID WINAPI XTL::EMUPATCH(D3DDevice_GetBackMaterial) -( - X_D3DMATERIAL8* pMaterial -) -{ - FUNC_EXPORTS - - LOG_FUNC_ONE_ARG(pMaterial); - - LOG_NOT_SUPPORTED(); - - HRESULT hRet = D3D_OK; - - // TODO: HACK: This is wrong, but better than nothing, right? - if (pMaterial) - { - hRet = g_pD3DDevice->GetMaterial(pMaterial); - DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetMaterial"); - } - - if (FAILED(hRet)) - { - EmuWarning("We're lying about getting a back material!"); - hRet = D3D_OK; - } -} - -// ****************************************************************** -// * patch: D3DDevice_SetRenderState_YuvEnable -// ****************************************************************** -VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_YuvEnable) -( - BOOL Enable -) -{ - LOG_FUNC_ONE_ARG(Enable); - - g_bColorSpaceConvertYuvToRgb = (Enable != FALSE); -} + +// ****************************************************************** +// * patch: D3DDevice_GetViewport +// ****************************************************************** +VOID WINAPI XTL::EMUPATCH(D3DDevice_GetViewport) +( + X_D3DVIEWPORT8 *pViewport +) +{ + FUNC_EXPORTS + + LOG_FUNC_ONE_ARG(pViewport); + + D3DVIEWPORT HostViewPort; + + HRESULT hRet = g_pD3DDevice->GetViewport(&HostViewPort); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport"); + + if (!g_ScaleViewport) { + *pViewport = HostViewPort; + } + else { + // Note : We cannot return the Xbox viewport as set in EMUPATCH(D3DDevice_SetViewport) + // because various Xbox D3D functions reset the Xbox viewport. Since we call comparable + // functions on host D3D, the host viewport is better suited as a return value; + // We just need to scale the host viewport back to Xbox dimensions - the exact opposite + // operation from the up-scaling that happens in EMUPATCH(D3DDevice_SetViewport). + + // Get current host render target dimensions + DWORD HostRenderTarget_Width; + DWORD HostRenderTarget_Height; + + if (GetHostRenderTargetDimensions(&HostRenderTarget_Width, &HostRenderTarget_Height)) { + + // Get current Xbox render target dimensions + DWORD XboxRenderTarget_Width = GetPixelContainerWidth(g_pXboxRenderTarget); + DWORD XboxRenderTarget_Height = GetPixelContainerHeigth(g_pXboxRenderTarget); + + // Scale host back to Xbox dimensions (avoiding hard-coding 640 x 480) + pViewport->X = ScaleDWORD(HostViewPort.X, HostRenderTarget_Width, XboxRenderTarget_Width); + pViewport->Y = ScaleDWORD(HostViewPort.Y, HostRenderTarget_Height, XboxRenderTarget_Height); + pViewport->Width = ScaleDWORD(HostViewPort.Width, HostRenderTarget_Width, XboxRenderTarget_Width); + pViewport->Height = ScaleDWORD(HostViewPort.Height, HostRenderTarget_Height, XboxRenderTarget_Height); + pViewport->MinZ = HostViewPort.MinZ; // No need scale Z for now + pViewport->MaxZ = HostViewPort.MaxZ; + } + else { + *pViewport = HostViewPort; + EmuWarning("GetHostRenderTargetDimensions failed - GetViewport returns host viewport instead!"); + } + } +} + +// ****************************************************************** +// * patch: D3D_BlockOnResource +// ****************************************************************** +void WINAPI XTL::EMUPATCH(D3D_BlockOnResource)( X_D3DResource* pResource ) +{ + FUNC_EXPORTS + + LOG_FUNC_ONE_ARG(pResource); + + // TODO: Implement + // NOTE: Azurik appears to call this directly from numerous points + LOG_UNIMPLEMENTED(); + +} + + +// ****************************************************************** +// * patch: IDirect3DResource8_IsBusy +// ****************************************************************** +BOOL WINAPI XTL::EMUPATCH(D3DResource_IsBusy) +( + X_D3DResource *pThis +) +{ + FUNC_EXPORTS + + /* too much output + LOG_FUNC_ONE_ARG(pThis); + //*/ + + return FALSE; +} + + +// ****************************************************************** +// * patch: D3DDevice_SetScissors +// ****************************************************************** +VOID WINAPI XTL::EMUPATCH(D3DDevice_SetScissors) +( + DWORD Count, + BOOL Exclusive, + CONST D3DRECT *pRects +) +{ + FUNC_EXPORTS + + LOG_FUNC_BEGIN + LOG_FUNC_ARG(Count) + LOG_FUNC_ARG(Exclusive) + LOG_FUNC_ARG(pRects) + LOG_FUNC_END; + + // TODO: Implement + LOG_UNIMPLEMENTED(); +} + +// ****************************************************************** +// * patch: D3DDevice_GetScissors +// ****************************************************************** +VOID WINAPI XTL::EMUPATCH(D3DDevice_GetScissors) +( + DWORD *pCount, + BOOL *pExclusive, + D3DRECT *pRects +) +{ + FUNC_EXPORTS + + LOG_FUNC_BEGIN + LOG_FUNC_ARG(pCount) + LOG_FUNC_ARG(pExclusive) + LOG_FUNC_ARG(pRects) + LOG_FUNC_END; + + // TODO: Save a copy of each scissor rect in case this function is called + // in conjunction with D3DDevice::SetScissors. So far, only Outrun2 uses + // this function. For now, just return the values within the current + // viewport. + + D3DVIEWPORT vp; + + HRESULT hRet = g_pD3DDevice->GetViewport( &vp ); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetViewport"); + + pRects->x1 = pRects->y1 = 0; + pRects->x2 = vp.Width; + pRects->y2 = vp.Height; + + pExclusive[0] = FALSE; +} + + +// ****************************************************************** +// * patch: D3DDevice_SetBackMaterial +// ****************************************************************** +VOID WINAPI XTL::EMUPATCH(D3DDevice_SetBackMaterial) +( + X_D3DMATERIAL8* pMaterial +) +{ + FUNC_EXPORTS + + LOG_FUNC_ONE_ARG(pMaterial); + + LOG_NOT_SUPPORTED(); +} + + + +// ****************************************************************** +// * patch: D3DDevice_GetBackMaterial +// ****************************************************************** +VOID WINAPI XTL::EMUPATCH(D3DDevice_GetBackMaterial) +( + X_D3DMATERIAL8* pMaterial +) +{ + FUNC_EXPORTS + + LOG_FUNC_ONE_ARG(pMaterial); + + LOG_NOT_SUPPORTED(); + + HRESULT hRet = D3D_OK; + + // TODO: HACK: This is wrong, but better than nothing, right? + if (pMaterial) + { + hRet = g_pD3DDevice->GetMaterial(pMaterial); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetMaterial"); + } + + if (FAILED(hRet)) + { + EmuWarning("We're lying about getting a back material!"); + hRet = D3D_OK; + } +} + +// ****************************************************************** +// * patch: D3DDevice_SetRenderState_YuvEnable +// ****************************************************************** +VOID WINAPI XTL::EMUPATCH(D3DDevice_SetRenderState_YuvEnable) +( + BOOL Enable +) +{ + LOG_FUNC_ONE_ARG(Enable); + + g_bColorSpaceConvertYuvToRgb = (Enable != FALSE); +} + +// ****************************************************************** +// * patch: D3DDevice_GetLight +// ****************************************************************** +VOID WINAPI XTL::EMUPATCH(D3DDevice_GetLight) +( + DWORD Index, + X_D3DLIGHT8 *pLight +) +{ + LOG_FUNC_BEGIN + LOG_FUNC_ARG(Index) + LOG_FUNC_ARG(pLight) + LOG_FUNC_END; + + HRESULT hRet = g_pD3DDevice->GetLight(Index, pLight); + DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetLight"); +} diff --git a/src/core/HLE/D3D8/XbConvert.h b/src/core/HLE/D3D8/XbConvert.h index 21cf32530..b124c5476 100644 --- a/src/core/HLE/D3D8/XbConvert.h +++ b/src/core/HLE/D3D8/XbConvert.h @@ -201,7 +201,7 @@ inline D3DSTENCILOP EmuXB2PC_D3DSTENCILOP(X_D3DSTENCILOP Value) return D3DSTENCILOP_DECR; default: - CxbxKrnlCleanup(LOG_PREFIX_D3DCVT, "Unknown D3DSTENCILOP (0x%.08X)", Value); + EmuLog(LOG_PREFIX_D3DCVT, LOG_LEVEL::WARNING, "Unknown D3DSTENCILOP (0x%.08X)", Value); } return (D3DSTENCILOP) Value; diff --git a/src/core/HLE/D3D8/XbD3D8Types.h b/src/core/HLE/D3D8/XbD3D8Types.h index 9e6f9906a..db8c9f6dd 100644 --- a/src/core/HLE/D3D8/XbD3D8Types.h +++ b/src/core/HLE/D3D8/XbD3D8Types.h @@ -516,8 +516,9 @@ typedef struct _CxbxVertexShader // we save them to be able to return them when necessary. UINT Size; DWORD *pDeclaration; + DWORD OriginalDeclarationSize; XTL::LPDIRECT3DVERTEXDECLARATION9 pHostDeclaration; - DWORD DeclarationSize; + DWORD HostDeclarationSize; DWORD *pFunction; DWORD FunctionSize; DWORD Type; diff --git a/src/core/HLE/D3D8/XbVertexShader.cpp b/src/core/HLE/D3D8/XbVertexShader.cpp index 8c881d348..05eb6ea18 100644 --- a/src/core/HLE/D3D8/XbVertexShader.cpp +++ b/src/core/HLE/D3D8/XbVertexShader.cpp @@ -2361,7 +2361,8 @@ DWORD XTL::EmuRecompileVshDeclaration ( DWORD *pDeclaration, D3DVERTEXELEMENT **ppRecompiledDeclaration, - DWORD *pDeclarationSize, + DWORD *pOriginalDeclarationSize, + DWORD *pHostDeclarationSize, boolean IsFixedFunction, CxbxVertexShaderInfo *pVertexShaderInfo ) @@ -2378,6 +2379,8 @@ DWORD XTL::EmuRecompileVshDeclaration // Calculate size of declaration DWORD DeclarationSize = VshGetDeclarationSize(pDeclaration); + *pOriginalDeclarationSize = DeclarationSize; + // For Direct3D9, we need to reserve at least twice the number of elements, as one token can generate two registers (in and out) : DeclarationSize *= sizeof(D3DVERTEXELEMENT) * 2; @@ -2386,7 +2389,7 @@ DWORD XTL::EmuRecompileVshDeclaration uint8_t *pRecompiledBufferOverflow = ((uint8_t*)pRecompiled) + DeclarationSize; *ppRecompiledDeclaration = pRecompiled; - *pDeclarationSize = DeclarationSize; + *pHostDeclarationSize = DeclarationSize; CxbxVertexShaderPatch PatchData = { 0 }; PatchData.pVertexShaderInfoToSet = pVertexShaderInfo; diff --git a/src/core/HLE/D3D8/XbVertexShader.h b/src/core/HLE/D3D8/XbVertexShader.h index adf4f70dd..34bd75527 100644 --- a/src/core/HLE/D3D8/XbVertexShader.h +++ b/src/core/HLE/D3D8/XbVertexShader.h @@ -54,7 +54,8 @@ extern DWORD EmuRecompileVshDeclaration ( DWORD *pDeclaration, D3DVERTEXELEMENT **ppRecompiledDeclaration, - DWORD *pDeclarationSize, + DWORD *pOriginalDeclarationSize, + DWORD *pHostDeclarationSize, boolean IsFixedFunction, XTL::CxbxVertexShaderInfo *pVertexShaderInfo ); diff --git a/src/core/HLE/Patches.cpp b/src/core/HLE/Patches.cpp index 1079840dd..f9e174780 100644 --- a/src/core/HLE/Patches.cpp +++ b/src/core/HLE/Patches.cpp @@ -91,7 +91,6 @@ std::map g_PatchTable = { PATCH_ENTRY("D3DDevice_GetBackBuffer2", XTL::EMUPATCH(D3DDevice_GetBackBuffer2), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetDisplayFieldStatus", XTL::EMUPATCH(D3DDevice_GetDisplayFieldStatus), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetGammaRamp", XTL::EMUPATCH(D3DDevice_GetGammaRamp), PATCH_HLE_D3D), - PATCH_ENTRY("D3DDevice_GetLight", XTL::EMUPATCH(D3DDevice_GetLight), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetMaterial", XTL::EMUPATCH(D3DDevice_GetMaterial), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetModelView", XTL::EMUPATCH(D3DDevice_GetModelView), PATCH_HLE_D3D), PATCH_ENTRY("D3DDevice_GetOverlayUpdateStatus", XTL::EMUPATCH(D3DDevice_GetOverlayUpdateStatus), PATCH_HLE_D3D), @@ -438,7 +437,12 @@ void EmuInstallPatches() void* GetPatchedFunctionTrampoline(std::string functionName) { if (g_FunctionHooks.find(functionName) != g_FunctionHooks.end()) { - return g_FunctionHooks[functionName].GetTrampoline(); + auto trampoline = g_FunctionHooks[functionName].GetTrampoline(); + if (trampoline == nullptr) { + EmuLog(CXBXR_MODULE::HLE, LOG_LEVEL::WARNING, "Failed to get XB_Trampoline for %s", functionName.c_str()); + } + + return trampoline; } return nullptr;