diff --git a/include/llvm/MC/MCTargetAsmParser.h b/include/llvm/MC/MCTargetAsmParser.h index fcb5edcef6a..4e3fd0d3a9e 100644 --- a/include/llvm/MC/MCTargetAsmParser.h +++ b/include/llvm/MC/MCTargetAsmParser.h @@ -18,6 +18,7 @@ class StringRef; class SMLoc; class AsmToken; class MCParsedAsmOperand; +class MCInst; template class SmallVectorImpl; /// MCTargetAsmParser - Generic interface to target specific assembly parsers. @@ -28,7 +29,8 @@ public: Match_InvalidOperand, Match_MissingFeature, Match_MnemonicFail, - Match_Success + Match_Success, + FIRST_TARGET_MATCH_RESULT_TY }; private: @@ -88,6 +90,12 @@ public: SmallVectorImpl &Operands, 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 diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 13a7f0b9024..1f298b3759c 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2981,9 +2981,10 @@ MatchAndEmitInstruction(SMLoc IDLoc, MCStreamer &Out) { MCInst Inst; unsigned ErrorInfo; - MatchResultTy MatchResult; + unsigned MatchResult; MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo); switch (MatchResult) { + default: break; case Match_Success: // Context sensitive operand constraints aren't handled by the matcher, // so check them here. diff --git a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp index a3b6aad0340..a8bc61e1415 100644 --- a/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp +++ b/lib/Target/MBlaze/AsmParser/MBlazeAsmParser.cpp @@ -323,6 +323,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned ErrorInfo; switch (MatchInstructionImpl(Operands, Inst, ErrorInfo)) { + default: break; case Match_Success: Out.EmitInstruction(Inst); return false; diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 6630fd00b2e..124b38818db 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -981,6 +981,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, // First, try a direct match. switch (MatchInstructionImpl(Operands, Inst, OrigErrorInfo)) { + default: break; case Match_Success: Out.EmitInstruction(Inst); return false; @@ -1019,7 +1020,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, // Check for the various suffix matches. Tmp[Base.size()] = Suffixes[0]; unsigned ErrorInfoIgnore; - MatchResultTy Match1, Match2, Match3, Match4; + unsigned Match1, Match2, Match3, Match4; Match1 = MatchInstructionImpl(Operands, Inst, ErrorInfoIgnore); Tmp[Base.size()] = Suffixes[1]; diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 2b00d8630bb..da1be260762 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -2179,7 +2179,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << " const SmallVectorImpl " << "&Operands);\n"; OS << " bool MnemonicIsValid(StringRef Mnemonic);\n"; - OS << " MatchResultTy MatchInstructionImpl(\n"; + OS << " unsigned MatchInstructionImpl(\n"; OS << " const SmallVectorImpl &Operands,\n"; OS << " MCInst &Inst, unsigned &ErrorInfo);\n"; @@ -2321,7 +2321,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << "}\n\n"; // Finally, build the match function. - OS << Target.getName() << ClassName << "::MatchResultTy " + OS << "unsigned " << Target.getName() << ClassName << "::\n" << "MatchInstructionImpl(const SmallVectorImpl" << " &Operands,\n"; @@ -2348,7 +2348,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " }\n\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 << " // wrong for all instances of the instruction.\n"; OS << " ErrorInfo = ~0U;\n"; @@ -2404,6 +2405,17 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { OS << " return Match_ConversionFail;\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. std::string InsnCleanupFn = 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 << " if (HadMatchOtherThanFeatures) return Match_MissingFeature;\n"; - OS << " return Match_InvalidOperand;\n"; + OS << " return RetCode;\n"; OS << "}\n\n"; if (Info.OperandMatchInfo.size())