From 63faf82d0377f0a878d643ca2aacc02c35811b3e Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Sat, 7 Jan 2012 01:33:34 +0000 Subject: Refactor. Store AsmParser info locally. A small step towards emitting match entries for multiple asm variants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147710 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/AsmMatcherEmitter.cpp | 83 +++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 38 deletions(-) (limited to 'utils') diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 3576cc9..1ab2d02 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -282,7 +282,11 @@ struct MatchableInfo { /// The suboperand index within SrcOpName, or -1 for the entire operand. int SubOpIdx; - explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1) {} + /// Register record if this token is singleton register. + Record *SingletonReg; + + explicit AsmOperand(StringRef T) : Token(T), Class(0), SubOpIdx(-1), + SingletonReg(0) {} }; /// ResOperand - This represents a single operand in the result instruction @@ -409,16 +413,18 @@ struct MatchableInfo { } void Initialize(const AsmMatcherInfo &Info, - SmallPtrSet &SingletonRegisters); + SmallPtrSet &SingletonRegisters, + int AsmVariantNo, std::string &RegisterPrefix); /// Validate - Return true if this matchable is a valid thing to match against /// and perform a bunch of validity checking. bool Validate(StringRef CommentDelimiter, bool Hack) const; - /// getSingletonRegisterForAsmOperand - If the specified token is a singleton - /// register, return the Record for it, otherwise return null. - Record *getSingletonRegisterForAsmOperand(unsigned i, - const AsmMatcherInfo &Info) const; + /// extractSingletonRegisterForAsmOperand - Extract singleton register, + /// if present, from specified token. + void + extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info, + std::string &RegisterPrefix); /// FindAsmOperand - Find the AsmOperand with the specified name and /// suboperand index. @@ -552,12 +558,6 @@ public: /// Target - The target information. CodeGenTarget &Target; - /// The AsmParser "RegisterPrefix" value. - std::string RegisterPrefix; - - /// The AsmParser variant number. - int AsmVariantNo; - /// The classes which are needed for matching. std::vector Classes; @@ -644,10 +644,11 @@ void MatchableInfo::dump() { } void MatchableInfo::Initialize(const AsmMatcherInfo &Info, - SmallPtrSet &SingletonRegisters) { + SmallPtrSet &SingletonRegisters, + int AsmVariantNo, std::string &RegisterPrefix) { // TODO: Eventually support asmparser for Variant != 0. AsmString = - CodeGenInstruction::FlattenAsmStringVariants(AsmString, Info.AsmVariantNo); + CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo); TokenizeAsmString(Info); @@ -660,7 +661,8 @@ void MatchableInfo::Initialize(const AsmMatcherInfo &Info, // Collect singleton registers, if used. for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) { - if (Record *Reg = getSingletonRegisterForAsmOperand(i, Info)) + extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix); + if (Record *Reg = AsmOperands[i].SingletonReg) SingletonRegisters.insert(Reg); } } @@ -740,7 +742,7 @@ void MatchableInfo::TokenizeAsmString(const AsmMatcherInfo &Info) { throw TGError(TheDef->getLoc(), "Instruction '" + TheDef->getName() + "' has no tokens"); Mnemonic = AsmOperands[0].Token; - // FIXME : Check and raise an error if it is register. + // FIXME : Check and raise an error if it is a register. if (Mnemonic[0] == '$') throw TGError(TheDef->getLoc(), "Invalid instruction mnemonic '" + Mnemonic.str() + "'!"); @@ -804,28 +806,33 @@ bool MatchableInfo::Validate(StringRef CommentDelimiter, bool Hack) const { return true; } -/// getSingletonRegisterForAsmOperand - If the specified token is a singleton -/// register, return the register name, otherwise return a null StringRef. -Record *MatchableInfo:: -getSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info) const{ +/// extractSingletonRegisterForAsmOperand - Extract singleton register, if present, +/// from specified token. +void MatchableInfo:: +extractSingletonRegisterForAsmOperand(unsigned i, const AsmMatcherInfo &Info, + std::string &RegisterPrefix) { StringRef Tok = AsmOperands[i].Token; - if (!Tok.startswith(Info.RegisterPrefix)) - return 0; + if (RegisterPrefix.empty()) { + if (i) { + std::string LoweredTok = Tok.lower(); + if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok)) + AsmOperands[i].SingletonReg = Reg->TheDef; + } else + if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(Tok)) + AsmOperands[i].SingletonReg = Reg->TheDef; + return; + } + + if (!Tok.startswith(RegisterPrefix)) + return; - StringRef RegName = Tok.substr(Info.RegisterPrefix.size()); + StringRef RegName = Tok.substr(RegisterPrefix.size()); if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName)) - return Reg->TheDef; + AsmOperands[i].SingletonReg = Reg->TheDef; // If there is no register prefix (i.e. "%" in "%eax"), then this may // be some random non-register token, just ignore it. - if (Info.RegisterPrefix.empty()) - return 0; - - // Otherwise, we have something invalid prefixed with the register prefix, - // such as %foo. - std::string Err = "unable to find register for '" + RegName.str() + - "' (which matches register prefix)"; - throw TGError(TheDef->getLoc(), Err); + return; } static std::string getEnumNameForToken(StringRef Str) { @@ -1109,9 +1116,7 @@ void AsmMatcherInfo::BuildOperandClasses() { AsmMatcherInfo::AsmMatcherInfo(Record *asmParser, CodeGenTarget &target, RecordKeeper &records) - : Records(records), AsmParser(asmParser), Target(target), - RegisterPrefix(AsmParser->getValueAsString("RegisterPrefix")), - AsmVariantNo(AsmParser->getValueAsInt("Variant")) { + : Records(records), AsmParser(asmParser), Target(target) { } /// BuildOperandMatchInfo - Build the necessary information to handle user @@ -1167,6 +1172,8 @@ void AsmMatcherInfo::BuildInfo() { } std::string CommentDelimiter = AsmParser->getValueAsString("CommentDelimiter"); + std::string RegisterPrefix = AsmParser->getValueAsString("RegisterPrefix"); + int AsmVariantNo = AsmParser->getValueAsInt("Variant"); // Parse the instructions; we need to do this first so that we can gather the // singleton register classes. @@ -1207,7 +1214,7 @@ void AsmMatcherInfo::BuildInfo() { OwningPtr II(new MatchableInfo(CGI)); - II->Initialize(*this, SingletonRegisters); + II->Initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); // Ignore instructions which shouldn't be matched and diagnose invalid // instruction definitions with an error. @@ -1240,7 +1247,7 @@ void AsmMatcherInfo::BuildInfo() { OwningPtr II(new MatchableInfo(Alias)); - II->Initialize(*this, SingletonRegisters); + II->Initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix); // Validate the alias definitions. II->Validate(CommentDelimiter, false); @@ -1268,7 +1275,7 @@ void AsmMatcherInfo::BuildInfo() { StringRef Token = Op.Token; // Check for singleton registers. - if (Record *RegRecord = II->getSingletonRegisterForAsmOperand(i, *this)) { + if (Record *RegRecord = II->AsmOperands[i].SingletonReg) { Op.Class = RegisterClasses[RegRecord]; assert(Op.Class && Op.Class->Registers.size() == 1 && "Unexpected class for singleton register"); -- cgit v1.1