From ba2b0ef809f66f1a6d334f000798fa2ceafab26f Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Fri, 23 Jan 2026 15:39:54 +0100 Subject: [PATCH] Enable automatic code formatting for X86Tables.h --- .clang-format-ignore | 2 +- .../Interface/Core/X86Tables/X86Tables.h | 386 +++++++++--------- 2 files changed, 202 insertions(+), 186 deletions(-) diff --git a/.clang-format-ignore b/.clang-format-ignore index 1e70ce6bb..ab479d6aa 100644 --- a/.clang-format-ignore +++ b/.clang-format-ignore @@ -2,7 +2,7 @@ Source/Common/cpp-optparse/* # Files with human-indented tables for readability - don't mess with these -FEXCore/Source/Interface/Core/X86Tables/* +FEXCore/Source/Interface/Core/X86Tables/*.cpp # Inline headers with list-like content that can't be processed individually Source/Tools/LinuxEmulation/LinuxSyscalls/x*/SyscallsNames.inl diff --git a/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h b/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h index 2dcbe0672..1fb01363a 100644 --- a/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h +++ b/FEXCore/Source/Interface/Core/X86Tables/X86Tables.h @@ -24,92 +24,98 @@ namespace FEXCore::X86Tables { struct X86InstInfo; namespace DecodeFlags { -constexpr uint32_t FLAG_OPERAND_SIZE = (1 << 0); -constexpr uint32_t FLAG_ADDRESS_SIZE = (1 << 1); -constexpr uint32_t FLAG_LOCK = (1 << 2); -constexpr uint32_t FLAG_LEGACY_PREFIX = (1 << 3); -constexpr uint32_t FLAG_REX_PREFIX = (1 << 4); -constexpr uint32_t FLAG_VSIB_BYTE = (1 << 5); -constexpr uint32_t FLAG_OPTION_AVX_W = (1 << 6); -constexpr uint32_t FLAG_REX_WIDENING = (1 << 7); -constexpr uint32_t FLAG_REX_XGPR_B = (1 << 8); -constexpr uint32_t FLAG_REX_XGPR_X = (1 << 9); -constexpr uint32_t FLAG_REX_XGPR_R = (1 << 10); -constexpr uint32_t FLAG_NO_PREFIX = (0b000 << 11); -constexpr uint32_t FLAG_ES_PREFIX = (0b001 << 11); -constexpr uint32_t FLAG_CS_PREFIX = (0b010 << 11); -constexpr uint32_t FLAG_SS_PREFIX = (0b011 << 11); -constexpr uint32_t FLAG_DS_PREFIX = (0b100 << 11); -constexpr uint32_t FLAG_FS_PREFIX = (0b101 << 11); -constexpr uint32_t FLAG_GS_PREFIX = (0b110 << 11); -constexpr uint32_t FLAG_SEGMENTS = (0b111 << 11); -constexpr uint32_t FLAG_FORCE_TSO = (1 << 14); -constexpr uint32_t FLAG_DECODED_MODRM = (1 << 15); -constexpr uint32_t FLAG_DECODED_SIB = (1 << 16); -constexpr uint32_t FLAG_REP_PREFIX = (1 << 17); -constexpr uint32_t FLAG_REPNE_PREFIX = (1 << 18); -// Size flags -constexpr uint32_t FLAG_SIZE_DST_OFF = 19; -constexpr uint32_t FLAG_SIZE_SRC_OFF = FLAG_SIZE_DST_OFF + 3; -constexpr uint32_t SIZE_MASK = 0b111; -constexpr uint32_t SIZE_DEF = 0b000; // This should be invalid past decoding -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 FLAG_OPERAND_SIZE = (1 << 0); + constexpr uint32_t FLAG_ADDRESS_SIZE = (1 << 1); + constexpr uint32_t FLAG_LOCK = (1 << 2); + constexpr uint32_t FLAG_LEGACY_PREFIX = (1 << 3); + constexpr uint32_t FLAG_REX_PREFIX = (1 << 4); + constexpr uint32_t FLAG_VSIB_BYTE = (1 << 5); + constexpr uint32_t FLAG_OPTION_AVX_W = (1 << 6); + constexpr uint32_t FLAG_REX_WIDENING = (1 << 7); + constexpr uint32_t FLAG_REX_XGPR_B = (1 << 8); + constexpr uint32_t FLAG_REX_XGPR_X = (1 << 9); + constexpr uint32_t FLAG_REX_XGPR_R = (1 << 10); + constexpr uint32_t FLAG_NO_PREFIX = (0b000 << 11); + constexpr uint32_t FLAG_ES_PREFIX = (0b001 << 11); + constexpr uint32_t FLAG_CS_PREFIX = (0b010 << 11); + constexpr uint32_t FLAG_SS_PREFIX = (0b011 << 11); + constexpr uint32_t FLAG_DS_PREFIX = (0b100 << 11); + constexpr uint32_t FLAG_FS_PREFIX = (0b101 << 11); + constexpr uint32_t FLAG_GS_PREFIX = (0b110 << 11); + constexpr uint32_t FLAG_SEGMENTS = (0b111 << 11); + constexpr uint32_t FLAG_FORCE_TSO = (1 << 14); + constexpr uint32_t FLAG_DECODED_MODRM = (1 << 15); + constexpr uint32_t FLAG_DECODED_SIB = (1 << 16); + constexpr uint32_t FLAG_REP_PREFIX = (1 << 17); + constexpr uint32_t FLAG_REPNE_PREFIX = (1 << 18); + // Size flags + constexpr uint32_t FLAG_SIZE_DST_OFF = 19; + constexpr uint32_t FLAG_SIZE_SRC_OFF = FLAG_SIZE_DST_OFF + 3; + constexpr uint32_t SIZE_MASK = 0b111; + constexpr uint32_t SIZE_DEF = 0b000; // This should be invalid past decoding + 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 FLAG_OPADDR_OFF = (FLAG_SIZE_SRC_OFF + 3); -constexpr uint32_t FLAG_OPADDR_STACKSIZE = 4; // Two level deep stack -constexpr uint32_t FLAG_OPADDR_FLAG_SIZE = 2; -constexpr uint32_t FLAG_OPADDR_MASK = (((1 << FLAG_OPADDR_STACKSIZE) - 1) << FLAG_OPADDR_OFF); + constexpr uint32_t FLAG_OPADDR_OFF = (FLAG_SIZE_SRC_OFF + 3); + constexpr uint32_t FLAG_OPADDR_STACKSIZE = 4; // Two level deep stack + constexpr uint32_t FLAG_OPADDR_FLAG_SIZE = 2; + constexpr uint32_t FLAG_OPADDR_MASK = (((1 << FLAG_OPADDR_STACKSIZE) - 1) << FLAG_OPADDR_OFF); -// 00 = NONE -constexpr uint32_t FLAG_OPERAND_SIZE_LAST = 0b01; -constexpr uint32_t FLAG_WIDENING_SIZE_LAST = 0b10; + // 00 = NONE + constexpr uint32_t FLAG_OPERAND_SIZE_LAST = 0b01; + constexpr uint32_t FLAG_WIDENING_SIZE_LAST = 0b10; -constexpr uint32_t GetSizeDstFlags(uint32_t Flags) { return (Flags >> FLAG_SIZE_DST_OFF) & SIZE_MASK; } -constexpr uint32_t GetSizeSrcFlags(uint32_t Flags) { return (Flags >> FLAG_SIZE_SRC_OFF) & SIZE_MASK; } - -constexpr uint32_t GenSizeDstSize(uint32_t Size) { return Size << FLAG_SIZE_DST_OFF; } -constexpr uint32_t GenSizeSrcSize(uint32_t Size) { return Size << FLAG_SIZE_SRC_OFF; } - -constexpr uint32_t GetOpAddr(uint32_t Flags, uint32_t Index) { - return (((Flags & FLAG_OPADDR_MASK) >> FLAG_OPADDR_OFF) >> (Index * 2)) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); -} - -inline void PushOpAddr(uint32_t *Flags, uint32_t Flag) { - uint32_t TmpFlags = *Flags; - uint32_t BottomOfStack = ((TmpFlags & FLAG_OPADDR_MASK) >> FLAG_OPADDR_OFF) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); - - TmpFlags &= ~(FLAG_OPADDR_MASK); - TmpFlags |= - (BottomOfStack << (FLAG_OPADDR_OFF + FLAG_OPADDR_FLAG_SIZE)) | - (Flag << FLAG_OPADDR_OFF); - - *Flags = TmpFlags; -} - -inline void PopOpAddrIf(uint32_t *Flags, uint32_t Flag) { - uint32_t TmpFlags = *Flags; - uint32_t BottomOfStack = ((TmpFlags & FLAG_OPADDR_MASK) >> FLAG_OPADDR_OFF) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); - - // Only pop the stack if the bottom flag is the one we care about - // Necessary for escape prefixes that overlap regular prefixes - if (BottomOfStack != Flag) { - return; + constexpr uint32_t GetSizeDstFlags(uint32_t Flags) { + return (Flags >> FLAG_SIZE_DST_OFF) & SIZE_MASK; + } + constexpr uint32_t GetSizeSrcFlags(uint32_t Flags) { + return (Flags >> FLAG_SIZE_SRC_OFF) & SIZE_MASK; } - uint32_t TopOfStack = ((TmpFlags & FLAG_OPADDR_MASK) >> (FLAG_OPADDR_OFF + FLAG_OPADDR_FLAG_SIZE)) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); + constexpr uint32_t GenSizeDstSize(uint32_t Size) { + return Size << FLAG_SIZE_DST_OFF; + } + constexpr uint32_t GenSizeSrcSize(uint32_t Size) { + return Size << FLAG_SIZE_SRC_OFF; + } - TmpFlags &= ~(FLAG_OPADDR_MASK); - TmpFlags |= (TopOfStack << FLAG_OPADDR_OFF); + constexpr uint32_t GetOpAddr(uint32_t Flags, uint32_t Index) { + return (((Flags & FLAG_OPADDR_MASK) >> FLAG_OPADDR_OFF) >> (Index * 2)) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); + } - *Flags = TmpFlags; -} + inline void PushOpAddr(uint32_t* Flags, uint32_t Flag) { + uint32_t TmpFlags = *Flags; + uint32_t BottomOfStack = ((TmpFlags & FLAG_OPADDR_MASK) >> FLAG_OPADDR_OFF) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); -} + TmpFlags &= ~(FLAG_OPADDR_MASK); + TmpFlags |= (BottomOfStack << (FLAG_OPADDR_OFF + FLAG_OPADDR_FLAG_SIZE)) | (Flag << FLAG_OPADDR_OFF); + + *Flags = TmpFlags; + } + + inline void PopOpAddrIf(uint32_t* Flags, uint32_t Flag) { + uint32_t TmpFlags = *Flags; + uint32_t BottomOfStack = ((TmpFlags & FLAG_OPADDR_MASK) >> FLAG_OPADDR_OFF) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); + + // Only pop the stack if the bottom flag is the one we care about + // Necessary for escape prefixes that overlap regular prefixes + if (BottomOfStack != Flag) { + return; + } + + uint32_t TopOfStack = ((TmpFlags & FLAG_OPADDR_MASK) >> (FLAG_OPADDR_OFF + FLAG_OPADDR_FLAG_SIZE)) & ((1 << FLAG_OPADDR_FLAG_SIZE) - 1); + + TmpFlags &= ~(FLAG_OPADDR_MASK); + TmpFlags |= (TopOfStack << FLAG_OPADDR_OFF); + + *Flags = TmpFlags; + } + +} // namespace DecodeFlags struct DecodedOperand { enum class OpType : uint8_t { @@ -194,8 +200,8 @@ struct DecodedOperand { int64_t Offset; uint8_t Scale; uint8_t Index; // ~0 invalid - uint8_t Base; // ~0 invalid - } SIB; // Shared with SIBRelocation + uint8_t Base; // ~0 invalid + } SIB; // Shared with SIBRelocation }; TypeUnion Data; @@ -209,7 +215,7 @@ struct DecodedInst { DecodedOperand Src[3]; // Constains the dispatcher handler pointer - X86InstInfo const* TableInfo; + const X86InstInfo* TableInfo; uint32_t Flags; uint16_t OP; @@ -222,18 +228,18 @@ struct DecodedInst { }; union ModRMDecoded { - uint8_t Hex{}; + uint8_t Hex {}; struct { - uint8_t rm : 3; + uint8_t rm : 3; uint8_t reg : 3; uint8_t mod : 2; }; }; union SIBDecoded { - uint8_t Hex{}; + uint8_t Hex {}; struct { - uint8_t base : 3; + uint8_t base : 3; uint8_t index : 3; uint8_t scale : 2; }; @@ -304,123 +310,136 @@ enum InstType { namespace InstFlags { -using InstFlagType = uint64_t; + using InstFlagType = uint64_t; -constexpr InstFlagType FLAGS_NONE = 0; -// The secondary Opcode Map uses prefix bytes to overlay more instruction -// But some instructions need to ignore this overlay and consume these prefixes. -constexpr InstFlagType FLAGS_NO_OVERLAY = (1ULL << 0); -// Some instructions partially ignore overlay -// Ignore OpSize (0x66) in this case -constexpr InstFlagType FLAGS_NO_OVERLAY66 = (1ULL << 1); -constexpr InstFlagType FLAGS_DEBUG_MEM_ACCESS = (1ULL << 2); -// Only SEXT if the instruction is operating in 64bit operand size -constexpr InstFlagType FLAGS_SRC_SEXT64BIT = (1ULL << 3); -constexpr InstFlagType FLAGS_BLOCK_END = (1ULL << 4); -constexpr InstFlagType FLAGS_SETS_RIP = (1ULL << 5); + constexpr InstFlagType FLAGS_NONE = 0; + // The secondary Opcode Map uses prefix bytes to overlay more instruction + // But some instructions need to ignore this overlay and consume these prefixes. + constexpr InstFlagType FLAGS_NO_OVERLAY = (1ULL << 0); + // Some instructions partially ignore overlay + // Ignore OpSize (0x66) in this case + constexpr InstFlagType FLAGS_NO_OVERLAY66 = (1ULL << 1); + constexpr InstFlagType FLAGS_DEBUG_MEM_ACCESS = (1ULL << 2); + // Only SEXT if the instruction is operating in 64bit operand size + constexpr InstFlagType FLAGS_SRC_SEXT64BIT = (1ULL << 3); + constexpr InstFlagType FLAGS_BLOCK_END = (1ULL << 4); + constexpr InstFlagType FLAGS_SETS_RIP = (1ULL << 5); -constexpr InstFlagType FLAGS_DISPLACE_SIZE_MUL_2 = (1ULL << 6); -constexpr InstFlagType FLAGS_DISPLACE_SIZE_DIV_2 = (1ULL << 7); -constexpr InstFlagType FLAGS_SRC_SEXT = (1ULL << 8); -constexpr InstFlagType FLAGS_MEM_OFFSET = (1ULL << 9); + constexpr InstFlagType FLAGS_DISPLACE_SIZE_MUL_2 = (1ULL << 6); + constexpr InstFlagType FLAGS_DISPLACE_SIZE_DIV_2 = (1ULL << 7); + constexpr InstFlagType FLAGS_SRC_SEXT = (1ULL << 8); + constexpr InstFlagType FLAGS_MEM_OFFSET = (1ULL << 9); -// Enables XMM based subflags -// Current reserved range for this SF is [10, 15] -constexpr InstFlagType FLAGS_XMM_FLAGS = (1ULL << 10); + // Enables XMM based subflags + // Current reserved range for this SF is [10, 15] + constexpr InstFlagType FLAGS_XMM_FLAGS = (1ULL << 10); -// X87 flags aliased to XMM flags selection -// Allows X87 instruction table that is abusing the flag for 64BIT selection to work -constexpr InstFlagType FLAGS_X87_FLAGS = (1ULL << 10); + // X87 flags aliased to XMM flags selection + // Allows X87 instruction table that is abusing the flag for 64BIT selection to work + constexpr InstFlagType FLAGS_X87_FLAGS = (1ULL << 10); // Non-XMM subflags - constexpr InstFlagType FLAGS_SF_DST_RAX = (1ULL << 11); - constexpr InstFlagType FLAGS_SF_DST_RDX = (1ULL << 12); - constexpr InstFlagType FLAGS_SF_SRC_RAX = (1ULL << 13); - constexpr InstFlagType FLAGS_SF_SRC_RCX = (1ULL << 14); - constexpr InstFlagType FLAGS_SF_REX_IN_BYTE = (1ULL << 15); + constexpr InstFlagType FLAGS_SF_DST_RAX = (1ULL << 11); + constexpr InstFlagType FLAGS_SF_DST_RDX = (1ULL << 12); + constexpr InstFlagType FLAGS_SF_SRC_RAX = (1ULL << 13); + constexpr InstFlagType FLAGS_SF_SRC_RCX = (1ULL << 14); + constexpr InstFlagType FLAGS_SF_REX_IN_BYTE = (1ULL << 15); // XMM subflags - constexpr InstFlagType FLAGS_SF_UNUSED = (1ULL << 11); // No assigned behavior yet - constexpr InstFlagType FLAGS_SF_DST_GPR = (1ULL << 12); - constexpr InstFlagType FLAGS_SF_SRC_GPR = (1ULL << 13); - constexpr InstFlagType FLAGS_SF_MMX_DST = (1ULL << 14); - constexpr InstFlagType FLAGS_SF_MMX_SRC = (1ULL << 15); - constexpr InstFlagType FLAGS_SF_MMX = FLAGS_SF_MMX_DST | FLAGS_SF_MMX_SRC; + constexpr InstFlagType FLAGS_SF_UNUSED = (1ULL << 11); // No assigned behavior yet + constexpr InstFlagType FLAGS_SF_DST_GPR = (1ULL << 12); + constexpr InstFlagType FLAGS_SF_SRC_GPR = (1ULL << 13); + constexpr InstFlagType FLAGS_SF_MMX_DST = (1ULL << 14); + constexpr InstFlagType FLAGS_SF_MMX_SRC = (1ULL << 15); + constexpr InstFlagType FLAGS_SF_MMX = FLAGS_SF_MMX_DST | FLAGS_SF_MMX_SRC; -// Enables MODRM specific subflags -// Current reserved range for this SF is [14, 17] -constexpr InstFlagType FLAGS_MODRM = (1ULL << 16); + // Enables MODRM specific subflags + // Current reserved range for this SF is [14, 17] + constexpr InstFlagType FLAGS_MODRM = (1ULL << 16); // With ModRM SF flag enabled // Direction of ModRM. Dst ^ Src // Set means destination is rm bits // Unset means src is rm bits - constexpr InstFlagType FLAGS_SF_MOD_DST = (1ULL << 17); + constexpr InstFlagType FLAGS_SF_MOD_DST = (1ULL << 17); // If the instruction is restricted to mem or reg only // 0b00 = Regular ModRM support // 0b01 = Memory accesses only // 0b10 = Register accesses only // 0b11 = - constexpr InstFlagType FLAGS_SF_MOD_MEM_ONLY = (1ULL << 18); - constexpr InstFlagType FLAGS_SF_MOD_REG_ONLY = (1ULL << 19); + constexpr InstFlagType FLAGS_SF_MOD_MEM_ONLY = (1ULL << 18); + constexpr InstFlagType FLAGS_SF_MOD_REG_ONLY = (1ULL << 19); - constexpr InstFlagType FLAGS_SF_MOD_ZERO_REG = (1ULL << 20); + constexpr InstFlagType FLAGS_SF_MOD_ZERO_REG = (1ULL << 20); -// x87 -constexpr InstFlagType FLAGS_POP = (1ULL << 21); + // x87 + constexpr InstFlagType FLAGS_POP = (1ULL << 21); -// Whether or not the instruction has a VEX prefix for the dest, first, or second source. -constexpr InstFlagType FLAGS_VEX_SRC_MASK = (0b11ULL << 22); -constexpr InstFlagType FLAGS_VEX_NO_OPERAND = (0b00ULL << 22); -constexpr InstFlagType FLAGS_VEX_DST = (0b01ULL << 22); -constexpr InstFlagType FLAGS_VEX_1ST_SRC = (0b10ULL << 22); -constexpr InstFlagType FLAGS_VEX_2ND_SRC = (0b11ULL << 22); -// Whether or not the instruction has a VSIB byte -constexpr InstFlagType FLAGS_VEX_VSIB = (1ULL << 24); -constexpr InstFlagType FLAGS_VEX_L_IGNORE = (1ULL << 25); -constexpr InstFlagType FLAGS_VEX_L_0 = (1ULL << 26); -constexpr InstFlagType FLAGS_VEX_L_1 = (1ULL << 27); + // Whether or not the instruction has a VEX prefix for the dest, first, or second source. + constexpr InstFlagType FLAGS_VEX_SRC_MASK = (0b11ULL << 22); + constexpr InstFlagType FLAGS_VEX_NO_OPERAND = (0b00ULL << 22); + constexpr InstFlagType FLAGS_VEX_DST = (0b01ULL << 22); + constexpr InstFlagType FLAGS_VEX_1ST_SRC = (0b10ULL << 22); + constexpr InstFlagType FLAGS_VEX_2ND_SRC = (0b11ULL << 22); + // Whether or not the instruction has a VSIB byte + constexpr InstFlagType FLAGS_VEX_VSIB = (1ULL << 24); + constexpr InstFlagType FLAGS_VEX_L_IGNORE = (1ULL << 25); + constexpr InstFlagType FLAGS_VEX_L_0 = (1ULL << 26); + constexpr InstFlagType FLAGS_VEX_L_1 = (1ULL << 27); -constexpr InstFlagType FLAGS_REX_W_0 = (1ULL << 28); -constexpr InstFlagType FLAGS_REX_W_1 = (1ULL << 29); + constexpr InstFlagType FLAGS_REX_W_0 = (1ULL << 28); + constexpr InstFlagType FLAGS_REX_W_1 = (1ULL << 29); -constexpr InstFlagType FLAGS_CALL = (1ULL << 30); + constexpr InstFlagType FLAGS_CALL = (1ULL << 30); -constexpr InstFlagType FLAGS_SIZE_DST_OFF = 58; -constexpr InstFlagType FLAGS_SIZE_SRC_OFF = FLAGS_SIZE_DST_OFF + 3; + constexpr InstFlagType FLAGS_SIZE_DST_OFF = 58; + constexpr InstFlagType FLAGS_SIZE_SRC_OFF = FLAGS_SIZE_DST_OFF + 3; -constexpr InstFlagType SIZE_MASK = 0b111; -constexpr InstFlagType SIZE_DEF = 0b000; -constexpr InstFlagType SIZE_8BIT = 0b001; -constexpr InstFlagType SIZE_16BIT = 0b010; -constexpr InstFlagType SIZE_32BIT = 0b011; -constexpr InstFlagType SIZE_64BIT = 0b100; -constexpr InstFlagType SIZE_128BIT = 0b101; -constexpr InstFlagType SIZE_256BIT = 0b110; -constexpr InstFlagType SIZE_64BITDEF = 0b111; // Default mode is 64bit instead of typical 32bit + constexpr InstFlagType SIZE_MASK = 0b111; + constexpr InstFlagType SIZE_DEF = 0b000; + constexpr InstFlagType SIZE_8BIT = 0b001; + constexpr InstFlagType SIZE_16BIT = 0b010; + constexpr InstFlagType SIZE_32BIT = 0b011; + constexpr InstFlagType SIZE_64BIT = 0b100; + constexpr InstFlagType SIZE_128BIT = 0b101; + constexpr InstFlagType SIZE_256BIT = 0b110; + constexpr InstFlagType SIZE_64BITDEF = 0b111; // Default mode is 64bit instead of typical 32bit #ifndef _WIN32 constexpr uint32_t DEFAULT_SYSCALL_FLAGS = FLAGS_NO_OVERLAY; #else - // Syscall ends a block on WIN32 because the instruction can update the CPU's RIP. + // Syscall ends a block on WIN32 because the instruction can update the CPU's RIP. constexpr uint32_t DEFAULT_SYSCALL_FLAGS = FLAGS_NO_OVERLAY | FLAGS_BLOCK_END; #endif -constexpr InstFlagType GetSizeDstFlags(InstFlagType Flags) { return (Flags >> FLAGS_SIZE_DST_OFF) & SIZE_MASK; } -constexpr InstFlagType GetSizeSrcFlags(InstFlagType Flags) { return (Flags >> FLAGS_SIZE_SRC_OFF) & SIZE_MASK; } + constexpr InstFlagType GetSizeDstFlags(InstFlagType Flags) { + return (Flags >> FLAGS_SIZE_DST_OFF) & SIZE_MASK; + } + constexpr InstFlagType GetSizeSrcFlags(InstFlagType Flags) { + return (Flags >> FLAGS_SIZE_SRC_OFF) & SIZE_MASK; + } -constexpr InstFlagType GenFlagsDstSize(InstFlagType Size) { return Size << FLAGS_SIZE_DST_OFF; } -constexpr InstFlagType GenFlagsSrcSize(InstFlagType Size) { return Size << FLAGS_SIZE_SRC_OFF; } -constexpr InstFlagType GenFlagsSameSize(InstFlagType Size) { return (Size << FLAGS_SIZE_DST_OFF) | (Size << FLAGS_SIZE_SRC_OFF); } -constexpr InstFlagType GenFlagsSizes(InstFlagType Dest, InstFlagType Src) { return (Dest << FLAGS_SIZE_DST_OFF) | (Src << FLAGS_SIZE_SRC_OFF); } + constexpr InstFlagType GenFlagsDstSize(InstFlagType Size) { + return Size << FLAGS_SIZE_DST_OFF; + } + constexpr InstFlagType GenFlagsSrcSize(InstFlagType Size) { + return Size << FLAGS_SIZE_SRC_OFF; + } + constexpr InstFlagType GenFlagsSameSize(InstFlagType Size) { + return (Size << FLAGS_SIZE_DST_OFF) | (Size << FLAGS_SIZE_SRC_OFF); + } + constexpr InstFlagType GenFlagsSizes(InstFlagType Dest, InstFlagType Src) { + return (Dest << FLAGS_SIZE_DST_OFF) | (Src << FLAGS_SIZE_SRC_OFF); + } // If it has an xmm subflag -#define HAS_XMM_SUBFLAG(x, flag) (((x) & (FEXCore::X86Tables::InstFlags::FLAGS_XMM_FLAGS | (flag))) == (FEXCore::X86Tables::InstFlags::FLAGS_XMM_FLAGS | (flag))) +#define HAS_XMM_SUBFLAG(x, flag) \ + (((x) & (FEXCore::X86Tables::InstFlags::FLAGS_XMM_FLAGS | (flag))) == (FEXCore::X86Tables::InstFlags::FLAGS_XMM_FLAGS | (flag))) // If it has non-xmm subflag #define HAS_NON_XMM_SUBFLAG(x, flag) (((x) & (FEXCore::X86Tables::InstFlags::FLAGS_XMM_FLAGS | (flag))) == (flag)) -} +} // namespace InstFlags constexpr uint8_t OpToIndex(uint8_t Op) { switch (Op) { @@ -450,32 +469,30 @@ constexpr uint8_t OpToIndex(uint8_t Op) { return 0; } -using DecodedOp = DecodedInst const*; +using DecodedOp = const DecodedInst*; using OpDispatchPtr = void (IR::OpDispatchBuilder::*)(DecodedOp); union OpDispatchPtrWrapper { OpDispatchPtr OpDispatch; - const struct X86InstInfo *Indirect; + const struct X86InstInfo* Indirect; }; struct X86InstInfo { - char const *Name; + const char* Name; InstType Type; InstFlags::InstFlagType Flags; ///< Must be larger than InstFlags enum uint8_t MoreBytes; OpDispatchPtrWrapper OpcodeDispatcher; - bool operator==(const X86InstInfo &b) const { - if (strcmp(Name, b.Name) != 0 || - Type != b.Type || - Flags != b.Flags || - MoreBytes != b.MoreBytes) + bool operator==(const X86InstInfo& b) const { + if (strcmp(Name, b.Name) != 0 || Type != b.Type || Flags != b.Flags || MoreBytes != b.MoreBytes) { return false; + } // We don't care if the opcode dispatcher differs return true; } - bool operator!=(const X86InstInfo &b) const { + bool operator!=(const X86InstInfo& b) const { return !operator==(b); } }; @@ -527,7 +544,7 @@ extern const std::array VEXTableGroupOps; extern const std::array VEXTableOps_AVX128; extern const std::array VEXTableGroupOps_AVX128; -template +template struct X86TablesInfoStruct { OpcodeType first; uint8_t second; @@ -537,11 +554,11 @@ using U8U8InfoStruct = X86TablesInfoStruct; using U16U8InfoStruct = X86TablesInfoStruct; template -constexpr static inline void GenerateTable(X86InstInfo *FinalTable, X86TablesInfoStruct const *LocalTable, size_t TableSize) { +constexpr static inline void GenerateTable(X86InstInfo* FinalTable, const X86TablesInfoStruct* LocalTable, size_t TableSize) { for (size_t j = 0; j < TableSize; ++j) { - X86TablesInfoStruct const &Op = LocalTable[j]; + const X86TablesInfoStruct& Op = LocalTable[j]; auto OpNum = Op.first; - X86InstInfo const &Info = Op.Info; + const X86InstInfo& Info = Op.Info; for (uint32_t i = 0; i < Op.second; ++i) { if (FinalTable[OpNum + i].Type != TYPE_UNKNOWN) { LOGMAN_MSG_A_FMT("Duplicate Entry {}->{}", FinalTable[OpNum + i].Name, Info.Name); @@ -555,19 +572,19 @@ constexpr static inline void GenerateTable(X86InstInfo *FinalTable, X86TablesInf }; template -constexpr static inline void GenerateTableWithCopy(X86InstInfo *FinalTable, X86TablesInfoStruct const *LocalTable, size_t TableSize, const X86InstInfo *OtherLocal) { +constexpr static inline void GenerateTableWithCopy(X86InstInfo* FinalTable, const X86TablesInfoStruct* LocalTable, + size_t TableSize, const X86InstInfo* OtherLocal) { for (size_t j = 0; j < TableSize; ++j) { - X86TablesInfoStruct const &Op = LocalTable[j]; + const X86TablesInfoStruct& Op = LocalTable[j]; auto OpNum = Op.first; - X86InstInfo const &Info = Op.Info; + const X86InstInfo& Info = Op.Info; for (uint32_t i = 0; i < Op.second; ++i) { if (FinalTable[OpNum + i].Type != TYPE_UNKNOWN) { LOGMAN_MSG_A_FMT("Duplicate Entry {}->{}", FinalTable[OpNum + i].Name, Info.Name); } if (Info.Type == TYPE_COPY_OTHER) { FinalTable[OpNum + i] = OtherLocal[OpNum + i]; - } - else { + } else { FinalTable[OpNum + i] = Info; } } @@ -575,11 +592,11 @@ constexpr static inline void GenerateTableWithCopy(X86InstInfo *FinalTable, X86T }; template -constexpr static inline void GenerateX87Table(X86InstInfo *FinalTable, X86TablesInfoStruct const *LocalTable, size_t TableSize) { +constexpr static inline void GenerateX87Table(X86InstInfo* FinalTable, const X86TablesInfoStruct* LocalTable, size_t TableSize) { for (size_t j = 0; j < TableSize; ++j) { - X86TablesInfoStruct const &Op = LocalTable[j]; + const X86TablesInfoStruct& Op = LocalTable[j]; auto OpNum = Op.first; - X86InstInfo const &Info = Op.Info; + const X86InstInfo& Info = Op.Info; for (uint32_t i = 0; i < Op.second; ++i) { if (FinalTable[OpNum + i].Type != TYPE_UNKNOWN) { LOGMAN_MSG_A_FMT("Duplicate Entry {}->{}", FinalTable[OpNum + i].Name, Info.Name); @@ -587,8 +604,7 @@ constexpr static inline void GenerateX87Table(X86InstInfo *FinalTable, X86Tables if ((OpNum & 0b11'000'000) == 0b11'000'000) { // If the mod field is 0b11 then it is a regular op FinalTable[OpNum + i] = Info; - } - else { + } else { // If the mod field is !0b11 then this instruction is duplicated through the whole mod [0b00, 0b10] range // and the modrm.rm space because that is used part of the instruction encoding if ((OpNum & 0b11'000'000) != 0) {