[llvm-commits] [llvm] r113166 - in /llvm/trunk: lib/Target/X86/AsmParser/X86AsmParser.cpp utils/TableGen/AsmMatcherEmitter.cpp
Chris Lattner
sabre at nondot.org
Mon Sep 6 13:08:02 PDT 2010
Author: lattner
Date: Mon Sep 6 15:08:02 2010
New Revision: 113166
URL: http://llvm.org/viewvc/llvm-project?rev=113166&view=rev
Log:
have tblgen detect when an instruction would have matched, but
failed because a subtarget feature was not enabled. Use this to
remove a bunch of hacks from the X86AsmParser for rejecting things
like popfl in 64-bit mode. Previously these hacks weren't needed,
but were important to get a message better than "invalid instruction"
when used in the wrong mode.
This also fixes bugs where pushal would not be rejected correctly in
32-bit mode (just pusha).
Modified:
llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=113166&r1=113165&r2=113166&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Mon Sep 6 15:08:02 2010
@@ -615,28 +615,13 @@
bool X86ATTAsmParser::
ParseInstruction(StringRef Name, SMLoc NameLoc,
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
- // The various flavors of pushf and popf use Requires<In32BitMode> and
- // Requires<In64BitMode>, but the assembler doesn't yet implement that.
- // For now, just do a manual check to prevent silent misencoding.
- if (Is64Bit) {
- if (Name == "popfl")
- return Error(NameLoc, "popfl cannot be encoded in 64-bit mode");
- if (Name == "pushfl")
- return Error(NameLoc, "pushfl cannot be encoded in 64-bit mode");
- if (Name == "pusha")
- return Error(NameLoc, "pusha cannot be encoded in 64-bit mode");
- } else {
- if (Name == "popfq")
- return Error(NameLoc, "popfq cannot be encoded in 32-bit mode");
- if (Name == "pushfq")
- return Error(NameLoc, "pushfq cannot be encoded in 32-bit mode");
- }
// The "Jump if rCX Zero" form jcxz is not allowed in 64-bit mode and
// the form jrcxz is not allowed in 32-bit mode.
if (Is64Bit) {
- if (Name == "jcxz")
- return Error(NameLoc, "jcxz cannot be encoded in 64-bit mode");
+ // FIXME: We can do jcxz/jecxz, we just don't have the encoding right yet.
+ if (Name == "jcxz" || Name == "jecxz")
+ return Error(NameLoc, Name + " cannot be encoded in 64-bit mode");
} else {
if (Name == "jrcxz")
return Error(NameLoc, "jrcxz cannot be encoded in 32-bit mode");
@@ -881,8 +866,15 @@
assert(!Operands.empty() && "Unexpect empty operand list!");
// First, try a direct match.
- if (MatchInstructionImpl(Operands, Inst) == Match_Success)
+ switch (MatchInstructionImpl(Operands, Inst)) {
+ case Match_Success:
return false;
+ case Match_MissingFeature:
+ Error(IDLoc, "instruction requires a CPU feature not currently enabled");
+ return true;
+ default:
+ break;
+ }
// FIXME: Ideally, we would only attempt suffix matches for things which are
// valid prefixes, and we could just infer the right unambiguous
@@ -901,13 +893,13 @@
// Check for the various suffix matches.
Tmp[Base.size()] = 'b';
- bool MatchB = MatchInstructionImpl(Operands, Inst) != Match_Success;
+ MatchResultTy MatchB = MatchInstructionImpl(Operands, Inst);
Tmp[Base.size()] = 'w';
- bool MatchW = MatchInstructionImpl(Operands, Inst) != Match_Success;
+ MatchResultTy MatchW = MatchInstructionImpl(Operands, Inst);
Tmp[Base.size()] = 'l';
- bool MatchL = MatchInstructionImpl(Operands, Inst) != Match_Success;
+ MatchResultTy MatchL = MatchInstructionImpl(Operands, Inst);
Tmp[Base.size()] = 'q';
- bool MatchQ = MatchInstructionImpl(Operands, Inst) != Match_Success;
+ MatchResultTy MatchQ = MatchInstructionImpl(Operands, Inst);
// Restore the old token.
Op->setTokenValue(Base);
@@ -915,23 +907,26 @@
// If exactly one matched, then we treat that as a successful match (and the
// instruction will already have been filled in correctly, since the failing
// matches won't have modified it).
- if (MatchB + MatchW + MatchL + MatchQ == 3)
+ unsigned NumSuccessfulMatches =
+ (MatchB == Match_Success) + (MatchW == Match_Success) +
+ (MatchL == Match_Success) + (MatchQ == Match_Success);
+ if (NumSuccessfulMatches == 1)
return false;
- // Otherwise, the match failed.
+ // Otherwise, the match failed, try to produce a decent error message.
// If we had multiple suffix matches, then identify this as an ambiguous
// match.
- if (MatchB + MatchW + MatchL + MatchQ != 4) {
+ if (NumSuccessfulMatches > 1) {
char MatchChars[4];
unsigned NumMatches = 0;
- if (!MatchB)
+ if (MatchB == Match_Success)
MatchChars[NumMatches++] = 'b';
- if (!MatchW)
+ if (MatchW == Match_Success)
MatchChars[NumMatches++] = 'w';
- if (!MatchL)
+ if (MatchL == Match_Success)
MatchChars[NumMatches++] = 'l';
- if (!MatchQ)
+ if (MatchQ == Match_Success)
MatchChars[NumMatches++] = 'q';
SmallString<126> Msg;
@@ -946,11 +941,26 @@
}
OS << ")";
Error(IDLoc, OS.str());
- } else {
- // FIXME: We should give nicer diagnostics about the exact failure.
- Error(IDLoc, "unrecognized instruction");
+ return true;
}
-
+
+ unsigned NumMatchFailures =
+ (MatchB == Match_Fail) + (MatchW == Match_Fail) +
+ (MatchL == Match_Fail) + (MatchQ == Match_Fail);
+
+
+ // If one instruction matched with a missing feature, report this as a
+ // missing feature.
+ if ((MatchB == Match_MissingFeature) + (MatchW == Match_MissingFeature) +
+ (MatchL == Match_MissingFeature) + (MatchQ == Match_MissingFeature) == 1&&
+ NumMatchFailures == 3) {
+ Error(IDLoc, "instruction requires a CPU feature not currently enabled");
+ return true;
+ }
+
+ // If all of these were an outright failure, report it in a useless way.
+ // FIXME: We should give nicer diagnostics about the exact failure.
+ Error(IDLoc, "unrecognized instruction");
return true;
}
Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=113166&r1=113165&r2=113166&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Mon Sep 6 15:08:02 2010
@@ -1549,7 +1549,7 @@
OS << " unsigned ComputeAvailableFeatures(const " <<
Target.getName() << "Subtarget *Subtarget) const;\n";
OS << " enum MatchResultTy {\n";
- OS << " Match_Success, Match_Fail\n";
+ OS << " Match_Success, Match_Fail, Match_MissingFeature\n";
OS << " };\n";
OS << " MatchResultTy MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
<< " &Operands, MCInst &Inst);\n\n";
@@ -1678,21 +1678,24 @@
// Emit code to search the table.
OS << " // Search the table.\n";
+ OS << " bool HadMatchOtherThanFeatures = false;\n";
OS << " for (const MatchEntry *it = MatchTable, "
<< "*ie = MatchTable + " << Info.Instructions.size()
<< "; it != ie; ++it) {\n";
- // Emit check that the required features are available.
- OS << " if ((AvailableFeatures & it->RequiredFeatures) "
- << "!= it->RequiredFeatures)\n";
- OS << " continue;\n";
-
// Emit check that the subclasses match.
for (unsigned i = 0; i != MaxNumOperands; ++i) {
OS << " if (!IsSubclass(Classes["
<< i << "], it->Classes[" << i << "]))\n";
OS << " continue;\n";
}
+
+ // Emit check that the required features are available.
+ OS << " if ((AvailableFeatures & it->RequiredFeatures) "
+ << "!= it->RequiredFeatures) {\n";
+ OS << " HadMatchOtherThanFeatures = true;\n";
+ OS << " continue;\n";
+ OS << " }\n";
OS << "\n";
OS << " ConvertToMCInst(it->ConvertFn, Inst, it->Opcode, Operands);\n";
@@ -1706,6 +1709,8 @@
OS << " return Match_Success;\n";
OS << " }\n\n";
+ OS << " // Okay, we had no match. Try to return a useful error code.\n";
+ OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n";
OS << " return Match_Fail;\n";
OS << "}\n\n";
More information about the llvm-commits
mailing list