diff options
author | Craig Topper <craig.topper@gmail.com> | 2011-10-04 06:30:42 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2011-10-04 06:30:42 +0000 |
commit | 6744a17dcfb941d9fdd869b9f06e20660e18ff88 (patch) | |
tree | fe947adef5aa0b66a85b739c60b8f83220d61913 /utils | |
parent | f143b79b78d1d244809fa59320f2af2edf4e1a86 (diff) | |
download | external_llvm-6744a17dcfb941d9fdd869b9f06e20660e18ff88.zip external_llvm-6744a17dcfb941d9fdd869b9f06e20660e18ff88.tar.gz external_llvm-6744a17dcfb941d9fdd869b9f06e20660e18ff88.tar.bz2 |
Add support in the disassembler for ignoring the L-bit on certain VEX instructions. Mark instructions that have this behavior. Fixes PR10676.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141065 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/X86DisassemblerTables.cpp | 28 | ||||
-rw-r--r-- | utils/TableGen/X86DisassemblerTables.h | 4 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.cpp | 11 | ||||
-rw-r--r-- | utils/TableGen/X86RecognizableInstr.h | 2 |
4 files changed, 25 insertions, 20 deletions
diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp index ac867dc..218a1a2 100644 --- a/utils/TableGen/X86DisassemblerTables.cpp +++ b/utils/TableGen/X86DisassemblerTables.cpp @@ -32,7 +32,8 @@ using namespace X86Disassembler; /// @param parent - The class that may be the superset /// @return - True if child is a subset of parent, false otherwise. static inline bool inheritsFrom(InstructionContext child, - InstructionContext parent) { + InstructionContext parent, + bool VEX_LIG = false) { if (child == parent) return true; @@ -68,33 +69,29 @@ static inline bool inheritsFrom(InstructionContext child, case IC_64BIT_XD_OPSIZE: return false; case IC_64BIT_REXW_XD: - return false; case IC_64BIT_REXW_XS: - return false; case IC_64BIT_REXW_OPSIZE: return false; case IC_VEX: - return inheritsFrom(child, IC_VEX_W); + return inheritsFrom(child, IC_VEX_W) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L)); case IC_VEX_XS: - return inheritsFrom(child, IC_VEX_W_XS); + return inheritsFrom(child, IC_VEX_W_XS) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_XS)); case IC_VEX_XD: - return inheritsFrom(child, IC_VEX_W_XD); + return inheritsFrom(child, IC_VEX_W_XD) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_XD)); case IC_VEX_OPSIZE: - return inheritsFrom(child, IC_VEX_W_OPSIZE); + return inheritsFrom(child, IC_VEX_W_OPSIZE) || + (VEX_LIG && inheritsFrom(child, IC_VEX_L_OPSIZE)); case IC_VEX_W: - return false; case IC_VEX_W_XS: - return false; case IC_VEX_W_XD: - return false; case IC_VEX_W_OPSIZE: return false; case IC_VEX_L: - return false; case IC_VEX_L_XS: - return false; case IC_VEX_L_XD: - return false; case IC_VEX_L_OPSIZE: return false; default: @@ -651,7 +648,8 @@ void DisassemblerTables::setTableFields(OpcodeType type, uint8_t opcode, const ModRMFilter &filter, InstrUID uid, - bool is32bit) { + bool is32bit, + bool ignoresVEX_L) { unsigned index; ContextDecision &decision = *Tables[type]; @@ -661,7 +659,7 @@ void DisassemblerTables::setTableFields(OpcodeType type, continue; if (inheritsFrom((InstructionContext)index, - InstructionSpecifiers[uid].insnContext)) + InstructionSpecifiers[uid].insnContext, ignoresVEX_L)) setTableFields(decision.opcodeDecisions[index].modRMDecisions[opcode], filter, uid, diff --git a/utils/TableGen/X86DisassemblerTables.h b/utils/TableGen/X86DisassemblerTables.h index ae126be..e148cd2 100644 --- a/utils/TableGen/X86DisassemblerTables.h +++ b/utils/TableGen/X86DisassemblerTables.h @@ -261,12 +261,14 @@ public: /// correspond to the desired instruction. /// @param uid - The unique ID of the instruction. /// @param is32bit - Instructon is only 32-bit + /// @param ignoresVEX_L - Instruction ignores VEX.L void setTableFields(OpcodeType type, InstructionContext insnContext, uint8_t opcode, const ModRMFilter &filter, InstrUID uid, - bool is32bit); + bool is32bit, + bool ignoresVEX_L); /// specForUID - Returns the instruction specifier for a given unique /// instruction ID. Used when resolving collisions. diff --git a/utils/TableGen/X86RecognizableInstr.cpp b/utils/TableGen/X86RecognizableInstr.cpp index 787e4df..f958966 100644 --- a/utils/TableGen/X86RecognizableInstr.cpp +++ b/utils/TableGen/X86RecognizableInstr.cpp @@ -217,6 +217,7 @@ RecognizableInstr::RecognizableInstr(DisassemblerTables &tables, HasVEXPrefix = Rec->getValueAsBit("hasVEXPrefix"); HasVEX_4VPrefix = Rec->getValueAsBit("hasVEX_4VPrefix"); HasVEX_WPrefix = Rec->getValueAsBit("hasVEX_WPrefix"); + IgnoresVEX_L = Rec->getValueAsBit("ignoresVEX_L"); HasLockPrefix = Rec->getValueAsBit("hasLockPrefix"); IsCodeGenOnly = Rec->getValueAsBit("isCodeGenOnly"); @@ -284,7 +285,9 @@ InstructionContext RecognizableInstr::insnContext() const { InstructionContext insnContext; if (HasVEX_4VPrefix || HasVEXPrefix) { - if (HasOpSizePrefix && HasVEX_LPrefix) + if (HasVEX_LPrefix && HasVEX_WPrefix) + llvm_unreachable("Don't support VEX.L and VEX.W together"); + else if (HasOpSizePrefix && HasVEX_LPrefix) insnContext = IC_VEX_L_OPSIZE; else if (HasOpSizePrefix && HasVEX_WPrefix) insnContext = IC_VEX_W_OPSIZE; @@ -957,7 +960,7 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { insnContext(), currentOpcode, *filter, - UID, Is32Bit); + UID, Is32Bit, IgnoresVEX_L); Spec->modifierType = MODIFIER_OPCODE; Spec->modifierBase = opcodeToSet; @@ -967,14 +970,14 @@ void RecognizableInstr::emitDecodePath(DisassemblerTables &tables) const { insnContext(), opcodeToSet, *filter, - UID, Is32Bit); + UID, Is32Bit, IgnoresVEX_L); } } else { tables.setTableFields(opcodeType, insnContext(), opcodeToSet, *filter, - UID, Is32Bit); + UID, Is32Bit, IgnoresVEX_L); Spec->modifierType = MODIFIER_NONE; Spec->modifierBase = opcodeToSet; diff --git a/utils/TableGen/X86RecognizableInstr.h b/utils/TableGen/X86RecognizableInstr.h index 0b600df..4441597 100644 --- a/utils/TableGen/X86RecognizableInstr.h +++ b/utils/TableGen/X86RecognizableInstr.h @@ -60,6 +60,8 @@ private: bool HasVEX_WPrefix; /// Inferred from the operands; indicates whether the L bit in the VEX prefix is set bool HasVEX_LPrefix; + // The ignoreVEX_L field from the record + bool IgnoresVEX_L; /// The hasLockPrefix field from the record bool HasLockPrefix; /// The isCodeGenOnly filed from the record |