diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-08-10 16:05:47 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-08-10 16:05:47 +0000 |
commit | fdb1f493ab6bcfb5603b9f497195492d92aceacb (patch) | |
tree | c292f3df7a28809cfef394444c99b3a82cdfc2b9 /utils | |
parent | bcf81629b85218ba86d9a4b4fdd06d4c182ba9a0 (diff) | |
download | llvm-fdb1f493ab6bcfb5603b9f497195492d92aceacb.tar.gz llvm-fdb1f493ab6bcfb5603b9f497195492d92aceacb.tar.bz2 llvm-fdb1f493ab6bcfb5603b9f497195492d92aceacb.tar.xz |
llvm-mc/AsmParser: Check for matches with super classes when matching
instruction operands.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78565 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index ef9ab20553..08353a4243 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -876,6 +876,53 @@ static void EmitClassifyOperand(CodeGenTarget &Target, OS << "}\n\n"; } +/// EmitIsSubclass - Emit the subclass predicate function. +static void EmitIsSubclass(CodeGenTarget &Target, + std::vector<ClassInfo*> &Infos, + raw_ostream &OS) { + OS << "/// IsSubclass - Compute whether \\arg A is a subclass of \\arg B.\n"; + OS << "static bool IsSubclass(MatchClassKind A, MatchClassKind B) {\n"; + OS << " if (A == B)\n"; + OS << " return true;\n\n"; + + OS << " switch (A) {\n"; + OS << " default:\n"; + OS << " return false;\n"; + for (std::vector<ClassInfo*>::iterator it = Infos.begin(), + ie = Infos.end(); it != ie; ++it) { + ClassInfo &A = **it; + + if (A.Kind != ClassInfo::Token) { + std::vector<StringRef> SuperClasses; + for (std::vector<ClassInfo*>::iterator it = Infos.begin(), + ie = Infos.end(); it != ie; ++it) { + ClassInfo &B = **it; + + if (&A != &B && A.getRootClass() == B.getRootClass() && A < B) + SuperClasses.push_back(B.Name); + } + + if (SuperClasses.empty()) + continue; + + OS << "\n case " << A.Name << ":\n"; + + if (SuperClasses.size() == 1) { + OS << " return B == " << SuperClasses.back() << ";\n\n"; + continue; + } + + OS << " switch (B) {\n"; + OS << " default: return false;\n"; + for (unsigned i = 0, e = SuperClasses.size(); i != e; ++i) + OS << " case " << SuperClasses[i] << ": return true;\n"; + OS << " }\n\n"; + } + } + OS << " }\n"; + OS << "}\n\n"; +} + typedef std::pair<std::string, std::string> StringPair; /// FindFirstNonCommonLetter - Find the first character in the keys of the @@ -1115,6 +1162,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { // Emit the routine to classify an operand. EmitClassifyOperand(Target, Info.Classes, OS); + // Emit the subclass predicate routine. + EmitIsSubclass(Target, Info.Classes, OS); + // Finally, build the match function. size_t MaxNumOperands = 0; @@ -1188,7 +1238,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) { << "*ie = MatchTable + " << Info.Instructions.size() << "; it != ie; ++it) {\n"; for (unsigned i = 0; i != MaxNumOperands; ++i) { - OS << " if (Classes[" << i << "] != it->Classes[" << i << "])\n"; + OS << " if (!IsSubclass(Classes[" + << i << "], it->Classes[" << i << "]))\n"; OS << " continue;\n"; } OS << "\n"; |