diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-08-10 18:41:10 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-08-10 18:41:10 +0000 |
commit | 338825c1928b956b2cbcc2c165a60afddd100398 (patch) | |
tree | ff202062dddcfe90ec2c604d1094571c44d91902 /utils | |
parent | b2d555b25bee4df71b33bbf9a3d730339b6a4081 (diff) |
llvm-mc/AsmMatcher: Change assembler parser match classes to their own record
structure.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78581 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 117 |
1 files changed, 56 insertions, 61 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 08353a4243..0356cb8363 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -87,11 +87,9 @@ #include <set> using namespace llvm; -namespace { static cl::opt<std::string> MatchPrefix("match-prefix", cl::init(""), cl::desc("Only match instructions with the given prefix")); -} /// FlattenVariants - Flatten an .td file assembly string by selecting the /// variant at index \arg N. @@ -455,21 +453,16 @@ private: /// Map of token to class information which has already been constructed. std::map<std::string, ClassInfo*> TokenClasses; - /// Map of operand name to class information which has already been - /// constructed. - std::map<std::string, ClassInfo*> OperandClasses; + /// The ClassInfo instance for registers. + ClassInfo *TheRegisterClass; - /// Map of user class names to kind value. - std::map<std::string, unsigned> UserClasses; + /// Map of AsmOperandClass records to their class information. + std::map<Record*, ClassInfo*> AsmOperandClasses; private: /// getTokenClass - Lookup or create the class for the given token. ClassInfo *getTokenClass(const StringRef &Token); - /// getUserClassKind - Lookup or create the kind value for the given class - /// name. - unsigned getUserClassKind(const StringRef &Name); - /// getOperandClass - Lookup or create the class for the given operand. ClassInfo *getOperandClass(const StringRef &Token, const CodeGenInstruction::OperandInfo &OI); @@ -543,66 +536,68 @@ ClassInfo *AsmMatcherInfo::getTokenClass(const StringRef &Token) { return Entry; } -unsigned AsmMatcherInfo::getUserClassKind(const StringRef &Name) { - unsigned &Entry = UserClasses[Name]; - - if (!Entry) - Entry = ClassInfo::UserClass0 + UserClasses.size() - 1; - - return Entry; -} - ClassInfo * AsmMatcherInfo::getOperandClass(const StringRef &Token, const CodeGenInstruction::OperandInfo &OI) { - unsigned SuperClass = ClassInfo::Invalid; - std::string ClassName; - if (OI.Rec->isSubClassOf("RegisterClass")) { - ClassName = "Reg"; - } else { - try { - ClassName = OI.Rec->getValueAsString("ParserMatchClass"); - assert(ClassName != "Reg" && "'Reg' class name is reserved!"); - } catch(...) { - PrintError(OI.Rec->getLoc(), "operand has no match class!"); - ClassName = "Invalid"; - } + if (OI.Rec->isSubClassOf("RegisterClass")) + return TheRegisterClass; + + assert(OI.Rec->isSubClassOf("Operand") && "Unexpected operand!"); + Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass"); + ClassInfo *CI = AsmOperandClasses[MatchClass]; - // Determine the super class. - try { - std::string SuperClassName = - OI.Rec->getValueAsString("ParserMatchSuperClass"); - SuperClass = getUserClassKind(SuperClassName); - } catch(...) { } + if (!CI) { + PrintError(OI.Rec->getLoc(), "operand has no match class!"); + throw std::string("ERROR: Missing match class!"); } - ClassInfo *&Entry = OperandClasses[ClassName]; - - if (!Entry) { - Entry = new ClassInfo(); - if (ClassName == "Reg") { - Entry->Kind = ClassInfo::Register; - Entry->SuperClassKind = SuperClass; + return CI; +} + +void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) { + // Build the assembly match class information. + + // Construct the "Reg" class. + // + // FIXME: This needs to dice up the RegisterClass instances. + ClassInfo *RegClass = TheRegisterClass = new ClassInfo(); + RegClass->Kind = ClassInfo::Register; + RegClass->SuperClassKind = ClassInfo::Invalid; + RegClass->ClassName = "Reg"; + RegClass->Name = "MCK_Reg"; + RegClass->ValueName = "<register class>"; + RegClass->PredicateMethod = "isReg"; + RegClass->RenderMethod = "addRegOperands"; + Classes.push_back(RegClass); + + // Build info for the user defined assembly operand classes. + std::vector<Record*> AsmOperands; + AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass"); + unsigned Index = 0; + for (std::vector<Record*>::iterator it = AsmOperands.begin(), + ie = AsmOperands.end(); it != ie; ++it, ++Index) { + ClassInfo *CI = new ClassInfo(); + CI->Kind = ClassInfo::UserClass0 + Index; + + Init *Super = (*it)->getValueInit("SuperClass"); + if (DefInit *DI = dynamic_cast<DefInit*>(Super)) { + CI->SuperClass = AsmOperandClasses[DI->getDef()]; + if (!CI->SuperClass) + PrintError((*it)->getLoc(), "Invalid super class reference!"); } else { - Entry->Kind = getUserClassKind(ClassName); - Entry->SuperClassKind = SuperClass; + assert(dynamic_cast<UnsetInit*>(Super) && "Unexpected SuperClass field!"); + CI->SuperClass = 0; } - Entry->ClassName = ClassName; - Entry->Name = "MCK_" + ClassName; - Entry->ValueName = OI.Rec->getName(); - Entry->PredicateMethod = "is" + ClassName; - Entry->RenderMethod = "add" + ClassName + "Operands"; - Classes.push_back(Entry); - } else { - // Verify the super class matches. - assert(SuperClass == Entry->SuperClassKind && - "Cannot redefine super class kind!"); + CI->ClassName = (*it)->getValueAsString("Name"); + CI->Name = "MCK_" + CI->ClassName; + CI->ValueName = (*it)->getName(); + CI->PredicateMethod = "is" + CI->ClassName; + CI->RenderMethod = "add" + CI->ClassName + "Operands"; + AsmOperandClasses[*it] = CI; + Classes.push_back(CI); } - - return Entry; -} -void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) { + // Build the instruction information. for (std::map<std::string, CodeGenInstruction>::const_iterator it = Target.getInstructions().begin(), ie = Target.getInstructions().end(); |