diff options
Diffstat (limited to 'utils/TableGen/AsmMatcherEmitter.cpp')
-rw-r--r-- | utils/TableGen/AsmMatcherEmitter.cpp | 61 |
1 files changed, 42 insertions, 19 deletions
diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index d8f2619..0d7c5ff 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -310,11 +310,16 @@ struct MatchableInfo { /// The suboperand index within SrcOpName, or -1 for the entire operand. int SubOpIdx; + /// Whether the token is "isolated", i.e., it is preceded and followed + /// by separators. + bool IsIsolatedToken; + /// Register record if this token is singleton register. Record *SingletonReg; - explicit AsmOperand(StringRef T) : Token(T), Class(nullptr), SubOpIdx(-1), - SingletonReg(nullptr) {} + explicit AsmOperand(bool IsIsolatedToken, StringRef T) + : Token(T), Class(nullptr), SubOpIdx(-1), + IsIsolatedToken(IsIsolatedToken), SingletonReg(nullptr) {} }; /// ResOperand - This represents a single operand in the result instruction @@ -572,6 +577,7 @@ struct MatchableInfo { private: void tokenizeAsmString(const AsmMatcherInfo &Info); + void addAsmOperand(size_t Start, size_t End); }; /// SubtargetFeatureInfo - Helper class for storing information on a subtarget @@ -811,6 +817,19 @@ void MatchableInfo::initialize(const AsmMatcherInfo &Info, DepMask ? !DepMask->getValue()->getAsUnquotedString().empty() : false; } +/// Append an AsmOperand for the given substring of AsmString. +void MatchableInfo::addAsmOperand(size_t Start, size_t End) { + StringRef String = AsmString; + StringRef Separators = "[]*! \t,"; + // Look for separators before and after to figure out is this token is + // isolated. Accept '$$' as that's how we escape '$'. + bool IsIsolatedToken = + (!Start || Separators.find(String[Start - 1]) != StringRef::npos || + String.substr(Start - 1, 2) == "$$") && + (End >= String.size() || Separators.find(String[End]) != StringRef::npos); + AsmOperands.push_back(AsmOperand(IsIsolatedToken, String.slice(Start, End))); +} + /// tokenizeAsmString - Tokenize a simplified assembly string. void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { StringRef String = AsmString; @@ -826,28 +845,28 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { case '\t': case ',': if (InTok) { - AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); + addAsmOperand(Prev, i); InTok = false; } if (!isspace(String[i]) && String[i] != ',') - AsmOperands.push_back(AsmOperand(String.substr(i, 1))); + addAsmOperand(i, i + 1); Prev = i + 1; break; case '\\': if (InTok) { - AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); + addAsmOperand(Prev, i); InTok = false; } ++i; assert(i != String.size() && "Invalid quoted character"); - AsmOperands.push_back(AsmOperand(String.substr(i, 1))); + addAsmOperand(i, i + 1); Prev = i + 1; break; case '$': { if (InTok) { - AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); + addAsmOperand(Prev, i); InTok = false; } @@ -860,7 +879,7 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { StringRef::iterator End = std::find(String.begin() + i, String.end(),'}'); assert(End != String.end() && "Missing brace in operand reference!"); size_t EndPos = End - String.begin(); - AsmOperands.push_back(AsmOperand(String.slice(i, EndPos+1))); + addAsmOperand(i, EndPos+1); Prev = EndPos + 1; i = EndPos; break; @@ -869,7 +888,7 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { case '.': if (!Info.AsmParser->getValueAsBit("MnemonicContainsDot")) { if (InTok) - AsmOperands.push_back(AsmOperand(String.slice(Prev, i))); + addAsmOperand(Prev, i); Prev = i; } InTok = true; @@ -880,7 +899,7 @@ void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) { } } if (InTok && Prev != String.size()) - AsmOperands.push_back(AsmOperand(String.substr(Prev))); + addAsmOperand(Prev, StringRef::npos); // The first token of the instruction is the mnemonic, which must be a // simple string, not a $foo variable or a singleton register. @@ -962,6 +981,12 @@ extractSingletonRegisterForAsmOperand(unsigned OperandNo, const AsmMatcherInfo &Info, std::string &RegisterPrefix) { StringRef Tok = AsmOperands[OperandNo].Token; + + // If this token is not an isolated token, i.e., it isn't separated from + // other tokens (e.g. with whitespace), don't interpret it as a register name. + if (!AsmOperands[OperandNo].IsIsolatedToken) + return; + if (RegisterPrefix.empty()) { std::string LoweredTok = Tok.lower(); if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok)) @@ -1224,8 +1249,8 @@ void AsmMatcherInfo::buildOperandClasses() { CI->Kind = ClassInfo::UserClass0 + Index; ListInit *Supers = Rec->getValueAsListInit("SuperClasses"); - for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { - DefInit *DI = dyn_cast<DefInit>(Supers->getElement(i)); + for (Init *I : Supers->getValues()) { + DefInit *DI = dyn_cast<DefInit>(I); if (!DI) { PrintError(Rec->getLoc(), "Invalid super class reference!"); continue; @@ -1510,7 +1535,7 @@ buildInstructionOperandReference(MatchableInfo *II, // Insert remaining suboperands after AsmOpIdx in II->AsmOperands. StringRef Token = Op->Token; // save this in case Op gets moved for (unsigned SI = 1, SE = Operands[Idx].MINumOperands; SI != SE; ++SI) { - MatchableInfo::AsmOperand NewAsmOp(Token); + MatchableInfo::AsmOperand NewAsmOp(/*IsIsolatedToken=*/true, Token); NewAsmOp.SubOpIdx = SI; II->AsmOperands.insert(II->AsmOperands.begin()+AsmOpIdx+SI, NewAsmOp); } @@ -1772,7 +1797,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName, getEnumNameForToken(AsmMatchConverter)); // Add the converter row for this instruction. - ConversionTable.push_back(std::vector<uint8_t>()); + ConversionTable.emplace_back(); ConversionTable.back().push_back(KindID); ConversionTable.back().push_back(CVT_Done); @@ -2136,8 +2161,7 @@ static void emitMatchTokenString(CodeGenTarget &Target, std::vector<StringMatcher::StringPair> Matches; for (const auto &CI : Infos) { if (CI.Kind == ClassInfo::Token) - Matches.push_back( - StringMatcher::StringPair(CI.ValueName, "return " + CI.Name + ";")); + Matches.emplace_back(CI.ValueName, "return " + CI.Name + ";"); } OS << "static MatchClassKind matchTokenString(StringRef Name) {\n"; @@ -2159,9 +2183,8 @@ static void emitMatchRegisterName(CodeGenTarget &Target, Record *AsmParser, if (Reg.TheDef->getValueAsString("AsmName").empty()) continue; - Matches.push_back( - StringMatcher::StringPair(Reg.TheDef->getValueAsString("AsmName"), - "return " + utostr(Reg.EnumValue) + ";")); + Matches.emplace_back(Reg.TheDef->getValueAsString("AsmName"), + "return " + utostr(Reg.EnumValue) + ";"); } OS << "static unsigned MatchRegisterName(StringRef Name) {\n"; |