summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2011-10-04 06:30:42 +0000
committerCraig Topper <craig.topper@gmail.com>2011-10-04 06:30:42 +0000
commit6744a17dcfb941d9fdd869b9f06e20660e18ff88 (patch)
treefe947adef5aa0b66a85b739c60b8f83220d61913 /utils
parentf143b79b78d1d244809fa59320f2af2edf4e1a86 (diff)
downloadllvm-6744a17dcfb941d9fdd869b9f06e20660e18ff88.tar.gz
llvm-6744a17dcfb941d9fdd869b9f06e20660e18ff88.tar.bz2
llvm-6744a17dcfb941d9fdd869b9f06e20660e18ff88.tar.xz
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.cpp28
-rw-r--r--utils/TableGen/X86DisassemblerTables.h4
-rw-r--r--utils/TableGen/X86RecognizableInstr.cpp11
-rw-r--r--utils/TableGen/X86RecognizableInstr.h2
4 files changed, 25 insertions, 20 deletions
diff --git a/utils/TableGen/X86DisassemblerTables.cpp b/utils/TableGen/X86DisassemblerTables.cpp
index ac867dcfa3..218a1a227c 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 ae126be569..e148cd26e8 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 787e4df081..f958966b81 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 0b600df872..4441597827 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