forked from OSchip/llvm-project
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:
parent
e24d324762
commit
120a96a721
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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())
|
||||||
|
|
Loading…
Reference in New Issue