MCTargetAsmParser target match predicate support.

Allow a target assembly parser to do context sensitive constraint checking
on a potential instruction match. This will be used, for example, to handle
Thumb2 IT block parsing.

llvm-svn: 137675
This commit is contained in:
Jim Grosbach 2011-08-15 23:03:29 +00:00
parent e24d324762
commit 120a96a721
5 changed files with 30 additions and 7 deletions

View File

@ -18,6 +18,7 @@ class StringRef;
class SMLoc; class SMLoc;
class AsmToken; class AsmToken;
class MCParsedAsmOperand; class MCParsedAsmOperand;
class MCInst;
template <typename T> class SmallVectorImpl; template <typename T> class SmallVectorImpl;
/// MCTargetAsmParser - Generic interface to target specific assembly parsers. /// MCTargetAsmParser - Generic interface to target specific assembly parsers.
@ -28,7 +29,8 @@ public:
Match_InvalidOperand, Match_InvalidOperand,
Match_MissingFeature, Match_MissingFeature,
Match_MnemonicFail, Match_MnemonicFail,
Match_Success Match_Success,
FIRST_TARGET_MATCH_RESULT_TY
}; };
private: private:
@ -88,6 +90,12 @@ public:
SmallVectorImpl<MCParsedAsmOperand*> &Operands, SmallVectorImpl<MCParsedAsmOperand*> &Operands,
MCStreamer &Out) = 0; MCStreamer &Out) = 0;
/// checkTargetMatchPredicate - Validate the instruction match against
/// any complex target predicates not expressible via match classes.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst) {
return Match_Success;
}
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -2981,9 +2981,10 @@ MatchAndEmitInstruction(SMLoc IDLoc,
MCStreamer &Out) { MCStreamer &Out) {
MCInst Inst; MCInst Inst;
unsigned ErrorInfo; unsigned ErrorInfo;
MatchResultTy MatchResult; unsigned MatchResult;
MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo);
switch (MatchResult) { switch (MatchResult) {
default: break;
case Match_Success: case Match_Success:
// Context sensitive operand constraints aren't handled by the matcher, // Context sensitive operand constraints aren't handled by the matcher,
// so check them here. // so check them here.

View File

@ -323,6 +323,7 @@ MatchAndEmitInstruction(SMLoc IDLoc,
unsigned ErrorInfo; unsigned ErrorInfo;
switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) {
default: break;
case Match_Success: case Match_Success:
Out.EmitInstruction(Inst); Out.EmitInstruction(Inst);
return false; return false;

View File

@ -981,6 +981,7 @@ MatchAndEmitInstruction(SMLoc IDLoc,
// First, try a direct match. // First, try a direct match.
switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) { switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) {
default: break;
case Match_Success: case Match_Success:
Out.EmitInstruction(Inst); Out.EmitInstruction(Inst);
return false; return false;
@ -1019,7 +1020,7 @@ MatchAndEmitInstruction(SMLoc IDLoc,
// Check for the various suffix matches. // Check for the various suffix matches.
Tmp[Base.size()] = Suffixes[0]; Tmp[Base.size()] = Suffixes[0];
unsigned ErrorInfoIgnore; unsigned ErrorInfoIgnore;
MatchResultTy Match1, Match2, Match3, Match4; unsigned Match1, Match2, Match3, Match4;
Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore);
Tmp[Base.size()] = Suffixes[1]; Tmp[Base.size()] = Suffixes[1];

View File

@ -2179,7 +2179,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
<< " const SmallVectorImpl<MCParsedAsmOperand*> " << " const SmallVectorImpl<MCParsedAsmOperand*> "
<< "&Operands);\n"; << "&Operands);\n";
OS << " bool MnemonicIsValid(StringRef Mnemonic);\n"; OS << " bool MnemonicIsValid(StringRef Mnemonic);\n";
OS << " MatchResultTy MatchInstructionImpl(\n"; OS << " unsigned MatchInstructionImpl(\n";
OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"; OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n";
OS << " MCInst &Inst, unsigned &ErrorInfo);\n"; OS << " MCInst &Inst, unsigned &ErrorInfo);\n";
@ -2321,7 +2321,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << "}\n\n"; OS << "}\n\n";
// Finally, build the match function. // Finally, build the match function.
OS << Target.getName() << ClassName << "::MatchResultTy " OS << "unsigned "
<< Target.getName() << ClassName << "::\n" << Target.getName() << ClassName << "::\n"
<< "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>" << "MatchInstructionImpl(const SmallVectorImpl<MCParsedAsmOperand*>"
<< " &Operands,\n"; << " &Operands,\n";
@ -2348,7 +2348,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " }\n\n"; OS << " }\n\n";
OS << " // Some state to try to produce better error messages.\n"; OS << " // Some state to try to produce better error messages.\n";
OS << " bool HadMatchOtherThanFeatures = false;\n\n"; OS << " bool HadMatchOtherThanFeatures = false;\n";
OS << " unsigned RetCode = Match_InvalidOperand;\n";
OS << " // Set ErrorInfo to the operand that mismatches if it is\n"; OS << " // Set ErrorInfo to the operand that mismatches if it is\n";
OS << " // wrong for all instances of the instruction.\n"; OS << " // wrong for all instances of the instruction.\n";
OS << " ErrorInfo = ~0U;\n"; OS << " ErrorInfo = ~0U;\n";
@ -2404,6 +2405,17 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " return Match_ConversionFail;\n"; OS << " return Match_ConversionFail;\n";
OS << "\n"; OS << "\n";
// Verify the instruction with the target-specific match predicate function.
OS << " // We have a potential match. Check the target predicate to\n"
<< " // handle any context sensitive constraints.\n"
<< " unsigned MatchResult;\n"
<< " if ((MatchResult = checkTargetMatchPredicate(Inst)) !="
<< " Match_Success) {\n"
<< " Inst.clear();\n"
<< " RetCode = MatchResult;\n"
<< " continue;\n"
<< " }\n\n";
// Call the post-processing function, if used. // Call the post-processing function, if used.
std::string InsnCleanupFn = std::string InsnCleanupFn =
AsmParser->getValueAsString("AsmParserInstCleanup"); AsmParser->getValueAsString("AsmParserInstCleanup");
@ -2415,7 +2427,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " // Okay, we had no match. Try to return a useful error code.\n"; OS << " // Okay, we had no match. Try to return a useful error code.\n";
OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n"; OS << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n";
OS << " return Match_InvalidOperand;\n"; OS << " return RetCode;\n";
OS << "}\n\n"; OS << "}\n\n";
if (Info.OperandMatchInfo.size()) if (Info.OperandMatchInfo.size())