summaryrefslogtreecommitdiffstats
path: root/llvm/utils/TableGen/AsmMatcherEmitter.cpp
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2016-02-05 19:59:33 +0000
committerTom Stellard <thomas.stellard@amd.com>2016-02-05 19:59:33 +0000
commitb9f235e5ced0a8119da0fe3e8e624e5b9a04d33d (patch)
treee221e43e18df49d9a35bdc62b3a2a91933e53bfc /llvm/utils/TableGen/AsmMatcherEmitter.cpp
parent7f83397d7219d2a93c85c0a37e95b64d56062f4b (diff)
downloadbcm5719-llvm-b9f235e5ced0a8119da0fe3e8e624e5b9a04d33d.tar.gz
bcm5719-llvm-b9f235e5ced0a8119da0fe3e8e624e5b9a04d33d.zip
TableGen: Add IsOptional field to AsmOperandClass
Summary: This makes it possible to specify some operands as optional to the AsmMatcher. Setting this field to true will prevent the AsmMatcher from emitting 'too few operands' errors when there are missing optional operands. Reviewers: olista01, ab Subscribers: nhaustov, arsenm, llvm-commits Differential Revision: http://reviews.llvm.org/D15755 llvm-svn: 259913
Diffstat (limited to 'llvm/utils/TableGen/AsmMatcherEmitter.cpp')
-rw-r--r--llvm/utils/TableGen/AsmMatcherEmitter.cpp16
1 files changed, 15 insertions, 1 deletions
diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 07dbd285305..103ed99e35c 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -200,6 +200,10 @@ struct ClassInfo {
/// For custom match classes: the diagnostic kind for when the predicate fails.
std::string DiagnosticType;
+
+ /// Is this operand optional and not always required.
+ bool IsOptional;
+
public:
/// isRegisterClass() - Check if this is a register class.
bool isRegisterClass() const {
@@ -1115,6 +1119,7 @@ ClassInfo *AsmMatcherInfo::getTokenClass(StringRef Token) {
Entry->RenderMethod = "<invalid>";
Entry->ParserMethod = "";
Entry->DiagnosticType = "";
+ Entry->IsOptional = false;
}
return Entry;
@@ -1249,6 +1254,7 @@ buildRegisterClasses(SmallPtrSetImpl<Record*> &SingletonRegisters) {
CI->Registers = RS;
// FIXME: diagnostic type.
CI->DiagnosticType = "";
+ CI->IsOptional = false;
RegisterSetClasses.insert(std::make_pair(RS, CI));
++Index;
}
@@ -1363,6 +1369,10 @@ void AsmMatcherInfo::buildOperandClasses() {
if (StringInit *SI = dyn_cast<StringInit>(DiagnosticType))
CI->DiagnosticType = SI->getValue();
+ Init *IsOptional = Rec->getValueInit("IsOptional");
+ if (BitInit *BI = dyn_cast<BitInit>(IsOptional))
+ CI->IsOptional = BI->getValue();
+
++Index;
}
}
@@ -2102,6 +2112,7 @@ static void emitMatchClassEnumeration(CodeGenTarget &Target,
<< "/// instruction matching.\n";
OS << "enum MatchClassKind {\n";
OS << " InvalidMatchClass = 0,\n";
+ OS << " OptionalMatchClass = 1,\n";
for (const auto &CI : Infos) {
OS << " " << CI.Name << ", // ";
if (CI.Kind == ClassInfo::Token) {
@@ -2188,6 +2199,8 @@ static void emitIsSubclass(CodeGenTarget &Target,
bool EmittedSwitch = false;
for (const auto &A : Infos) {
std::vector<StringRef> SuperClasses;
+ if (A.IsOptional)
+ SuperClasses.push_back("OptionalMatchClass");
for (const auto &B : Infos) {
if (&A != &B && A.isSubsetOf(B))
SuperClasses.push_back(B.Name);
@@ -3100,7 +3113,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " auto Formal = static_cast<MatchClassKind>(it->Classes[i]);\n";
OS << " if (i" << (HasMnemonicFirst ? "+1" : "")
<< " >= Operands.size()) {\n";
- OS << " OperandsValid = (Formal == " <<"InvalidMatchClass);\n";
+ OS << " OperandsValid = (Formal == " <<"InvalidMatchClass) || "
+ "isSubclass(Formal, OptionalMatchClass);\n";
OS << " if (!OperandsValid) ErrorInfo = i"
<< (HasMnemonicFirst ? "+1" : "") << ";\n";
OS << " break;\n";
OpenPOWER on IntegriCloud