From 7a4d0fbfd34d5541defd5f60237540d08ba8eb00 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sun, 17 Nov 2019 17:00:20 -0800 Subject: [PATCH] Fixes bug in 64bit def mod instructions that are in 16bit mode These would have been forced to 64bit when they would have wanted to be operating in 16bit mode. Fixes that. --- Source/Interface/Core/Frontend.cpp | 12 ++++++++---- Source/Interface/Core/X86Tables/BaseTables.cpp | 12 ++++++------ .../Core/X86Tables/PrimaryGroupTables.cpp | 6 +++--- include/FEXCore/Debug/X86Tables.h | 17 +++++++++-------- 4 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Source/Interface/Core/Frontend.cpp b/Source/Interface/Core/Frontend.cpp index dc3b31a07..889cf12cf 100644 --- a/Source/Interface/Core/Frontend.cpp +++ b/Source/Interface/Core/Frontend.cpp @@ -215,13 +215,15 @@ bool Decoder::NormalOp(FEXCore::X86Tables::X86InstInfo const *Info, uint16_t Op) DecodeInst->Flags |= DecodeFlags::GenSizeDstSize(DecodeFlags::SIZE_128BIT); } else if (DecodeInst->Flags & DecodeFlags::FLAG_OPERAND_SIZE && - DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_DEF) { + (DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_DEF || + DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) { // See table 1-2. Operand-Size Overrides for this decoding // If the default operating mode is 32bit and we have the operand size flag then the operating size drops to 16bit DecodeInst->Flags |= DecodeFlags::GenSizeDstSize(DecodeFlags::SIZE_16BIT); } else if (DecodeInst->Flags & DecodeFlags::FLAG_REX_WIDENING || - DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT) { + DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT || + DstSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF) { DecodeInst->Flags |= DecodeFlags::GenSizeDstSize(DecodeFlags::SIZE_64BIT); } else { @@ -239,13 +241,15 @@ bool Decoder::NormalOp(FEXCore::X86Tables::X86InstInfo const *Info, uint16_t Op) DecodeInst->Flags |= DecodeFlags::GenSizeSrcSize(DecodeFlags::SIZE_128BIT); } else if (DecodeInst->Flags & DecodeFlags::FLAG_OPERAND_SIZE && - SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_DEF) { + (SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_DEF || + SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF)) { // See table 1-2. Operand-Size Overrides for this decoding // If the default operating mode is 32bit and we have the operand size flag then the operating size drops to 16bit DecodeInst->Flags |= DecodeFlags::GenSizeSrcSize(DecodeFlags::SIZE_16BIT); } else if (DecodeInst->Flags & DecodeFlags::FLAG_REX_WIDENING || - SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT) { + SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BIT || + SrcSizeFlag == FEXCore::X86Tables::InstFlags::SIZE_64BITDEF) { DecodeInst->Flags |= DecodeFlags::GenSizeSrcSize(DecodeFlags::SIZE_64BIT); } else { diff --git a/Source/Interface/Core/X86Tables/BaseTables.cpp b/Source/Interface/Core/X86Tables/BaseTables.cpp index 7988970a7..ca8ad49d0 100644 --- a/Source/Interface/Core/X86Tables/BaseTables.cpp +++ b/Source/Interface/Core/X86Tables/BaseTables.cpp @@ -89,14 +89,14 @@ void InitializeBaseTables() { {0x3D, 1, X86InstInfo{"CMP", TYPE_INST, FLAGS_SF_DST_RAX | FLAGS_SRC_SEXT | FLAGS_DISPLACE_SIZE_DIV_2, 4, nullptr}}, {0x3F, 1, X86InstInfo{"[INV]", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, - {0x50, 8, X86InstInfo{"PUSH", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_SF_REX_IN_BYTE | FLAGS_DEBUG_MEM_ACCESS , 0, nullptr}}, - {0x58, 8, X86InstInfo{"POP", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_SF_REX_IN_BYTE | FLAGS_DEBUG_MEM_ACCESS , 0, nullptr}}, + {0x50, 8, X86InstInfo{"PUSH", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_SF_REX_IN_BYTE | FLAGS_DEBUG_MEM_ACCESS , 0, nullptr}}, + {0x58, 8, X86InstInfo{"POP", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_SF_REX_IN_BYTE | FLAGS_DEBUG_MEM_ACCESS , 0, nullptr}}, {0x60, 2, X86InstInfo{"[INV]", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, {0x62, 1, X86InstInfo{"", TYPE_GROUP_EVEX, FLAGS_NONE, 0, nullptr}}, {0x63, 1, X86InstInfo{"MOVSXD", TYPE_INST, GenFlagsDstSize(SIZE_64BIT) | FLAGS_MODRM, 0, nullptr}}, - {0x68, 1, X86InstInfo{"PUSH", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_DISPLACE_SIZE_DIV_2 , 4, nullptr}}, + {0x68, 1, X86InstInfo{"PUSH", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_DISPLACE_SIZE_DIV_2 | FLAGS_SRC_SEXT, 4, nullptr}}, {0x69, 1, X86InstInfo{"IMUL", TYPE_INST, FLAGS_MODRM | FLAGS_SRC_SEXT | FLAGS_DISPLACE_SIZE_DIV_2, 4, nullptr}}, {0x6A, 1, X86InstInfo{"PUSH", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_SRC_SEXT , 1, nullptr}}, {0x6B, 1, X86InstInfo{"IMUL", TYPE_INST, FLAGS_MODRM | FLAGS_SRC_SEXT , 1, nullptr}}, @@ -143,8 +143,8 @@ void InitializeBaseTables() { // These three are all X87 instructions {0x9B, 1, X86InstInfo{"FWAIT", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, - {0x9C, 1, X86InstInfo{"PUSHF", TYPE_INVALID, GenFlagsSameSize(SIZE_64BIT) , 0, nullptr}}, - {0x9D, 1, X86InstInfo{"POPF", TYPE_INVALID, GenFlagsSameSize(SIZE_64BIT) , 0, nullptr}}, + {0x9C, 1, X86InstInfo{"PUSHF", TYPE_INVALID, GenFlagsSameSize(SIZE_64BITDEF), 0, nullptr}}, + {0x9D, 1, X86InstInfo{"POPF", TYPE_INVALID, GenFlagsSameSize(SIZE_64BITDEF), 0, nullptr}}, {0x9E, 1, X86InstInfo{"SAHF", TYPE_INST, FLAGS_NONE, 0, nullptr}}, {0x9F, 1, X86InstInfo{"LAHF", TYPE_INST, FLAGS_NONE, 0, nullptr}}, @@ -172,7 +172,7 @@ void InitializeBaseTables() { {0xC2, 1, X86InstInfo{"RET", TYPE_INST, FLAGS_SETS_RIP | FLAGS_BLOCK_END, 2, nullptr}}, {0xC3, 1, X86InstInfo{"RET", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_SETS_RIP | FLAGS_BLOCK_END , 0, nullptr}}, {0xC8, 1, X86InstInfo{"ENTER", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS , 3, nullptr}}, - {0xC9, 1, X86InstInfo{"LEAVE", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_SETS_RIP | FLAGS_BLOCK_END , 0, nullptr}}, + {0xC9, 1, X86InstInfo{"LEAVE", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_SETS_RIP | FLAGS_BLOCK_END , 0, nullptr}}, {0xCA, 2, X86InstInfo{"RETF", TYPE_PRIV, GenFlagsSameSize(SIZE_64BIT) | FLAGS_SETS_RIP | FLAGS_BLOCK_END, 0, nullptr}}, {0xCC, 1, X86InstInfo{"INT3", TYPE_INST, FLAGS_DEBUG, 0, nullptr}}, {0xCD, 1, X86InstInfo{"INT", TYPE_INST, FLAGS_DEBUG , 1, nullptr}}, diff --git a/Source/Interface/Core/X86Tables/PrimaryGroupTables.cpp b/Source/Interface/Core/X86Tables/PrimaryGroupTables.cpp index 9f761a344..6fcfdd3ed 100644 --- a/Source/Interface/Core/X86Tables/PrimaryGroupTables.cpp +++ b/Source/Interface/Core/X86Tables/PrimaryGroupTables.cpp @@ -119,11 +119,11 @@ void InitializePrimaryGroupTables() { // GROUP 5 {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 0), 1, X86InstInfo{"INC", TYPE_INST, FLAGS_MODRM | FLAGS_SF_MOD_DST, 0, nullptr}}, {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 1), 1, X86InstInfo{"DEC", TYPE_INST, FLAGS_MODRM | FLAGS_SF_MOD_DST, 0, nullptr}}, - {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 2), 1, X86InstInfo{"CALL", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_SETS_RIP | FLAGS_MODRM | FLAGS_BLOCK_END , 0, nullptr}}, + {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 2), 1, X86InstInfo{"CALL", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_SETS_RIP | FLAGS_MODRM | FLAGS_BLOCK_END , 0, nullptr}}, {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 3), 1, X86InstInfo{"CALLF", TYPE_INST, FLAGS_SETS_RIP | FLAGS_MODRM | FLAGS_BLOCK_END, 0, nullptr}}, - {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 4), 1, X86InstInfo{"JMP", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_SETS_RIP | FLAGS_MODRM | FLAGS_BLOCK_END , 0, nullptr}}, + {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 4), 1, X86InstInfo{"JMP", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_SETS_RIP | FLAGS_MODRM | FLAGS_BLOCK_END , 0, nullptr}}, {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 5), 1, X86InstInfo{"JMPF", TYPE_INST, FLAGS_SETS_RIP | FLAGS_MODRM | FLAGS_BLOCK_END, 0, nullptr}}, - {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 6), 1, X86InstInfo{"PUSH", TYPE_INST, GenFlagsSameSize(SIZE_64BIT) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_MODRM | FLAGS_SF_MOD_DST, 0, nullptr}}, + {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 6), 1, X86InstInfo{"PUSH", TYPE_INST, GenFlagsSameSize(SIZE_64BITDEF) | FLAGS_DEBUG_MEM_ACCESS | FLAGS_MODRM | FLAGS_SF_MOD_DST, 0, nullptr}}, {OPD(TYPE_GROUP_5, OpToIndex(0xFF), 7), 1, X86InstInfo{"", TYPE_INVALID, FLAGS_NONE, 0, nullptr}}, // GROUP 11 diff --git a/include/FEXCore/Debug/X86Tables.h b/include/FEXCore/Debug/X86Tables.h index a49a8b469..3e8eaab77 100644 --- a/include/FEXCore/Debug/X86Tables.h +++ b/include/FEXCore/Debug/X86Tables.h @@ -249,14 +249,15 @@ constexpr uint32_t FLAGS_MODRM = (1 << 16); constexpr uint32_t FLAGS_SIZE_DST_OFF = 20; constexpr uint32_t FLAGS_SIZE_SRC_OFF = FLAGS_SIZE_DST_OFF + 3; -constexpr uint32_t SIZE_MASK = 0b111; -constexpr uint32_t SIZE_DEF = 0b000; -constexpr uint32_t SIZE_8BIT = 0b001; -constexpr uint32_t SIZE_16BIT = 0b010; -constexpr uint32_t SIZE_32BIT = 0b011; -constexpr uint32_t SIZE_64BIT = 0b100; -constexpr uint32_t SIZE_128BIT = 0b101; -constexpr uint32_t SIZE_256BIT = 0b110; +constexpr uint32_t SIZE_MASK = 0b111; +constexpr uint32_t SIZE_DEF = 0b000; +constexpr uint32_t SIZE_8BIT = 0b001; +constexpr uint32_t SIZE_16BIT = 0b010; +constexpr uint32_t SIZE_32BIT = 0b011; +constexpr uint32_t SIZE_64BIT = 0b100; +constexpr uint32_t SIZE_128BIT = 0b101; +constexpr uint32_t SIZE_256BIT = 0b110; +constexpr uint32_t SIZE_64BITDEF = 0b111; // Default mode is 64bit instead of typical 32bit inline uint32_t GetSizeDstFlags(uint32_t Flags) { return (Flags >> FLAGS_SIZE_DST_OFF) & SIZE_MASK; } inline uint32_t GetSizeSrcFlags(uint32_t Flags) { return (Flags >> FLAGS_SIZE_SRC_OFF) & SIZE_MASK; }