private:
void tokenizeAsmString(AsmMatcherInfo const &Info,
AsmVariantInfo const &Variant);
- void addAsmOperand(size_t Start, size_t End,
- std::string const &SeparatorCharacters);
+ void addAsmOperand(StringRef Token, bool IsIsolatedToken = false);
};
/// SubtargetFeatureInfo - Helper class for storing information on a subtarget
}
/// Append an AsmOperand for the given substring of AsmString.
-void MatchableInfo::addAsmOperand(size_t Start, size_t End,
- std::string const &Separators) {
- StringRef String = AsmString;
- // 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)));
+void MatchableInfo::addAsmOperand(StringRef Token, bool IsIsolatedToken) {
+ AsmOperands.push_back(AsmOperand(IsIsolatedToken, Token));
}
/// tokenizeAsmString - Tokenize a simplified assembly string.
StringRef String = AsmString;
size_t Prev = 0;
bool InTok = false;
- std::string Separators = Variant.TokenizingCharacters +
- Variant.SeparatorCharacters;
+ bool IsIsolatedToken = true;
for (size_t i = 0, e = String.size(); i != e; ++i) {
- if(Variant.BreakCharacters.find(String[i]) != std::string::npos) {
- if(InTok) {
- addAsmOperand(Prev, i, Separators);
+ char Char = String[i];
+ if (Variant.BreakCharacters.find(Char) != std::string::npos) {
+ if (InTok) {
+ addAsmOperand(String.slice(Prev, i), false);
Prev = i;
+ IsIsolatedToken = false;
}
InTok = true;
continue;
}
- if(Variant.TokenizingCharacters.find(String[i]) != std::string::npos) {
- if(InTok) {
- addAsmOperand(Prev, i, Separators);
+ if (Variant.TokenizingCharacters.find(Char) != std::string::npos) {
+ if (InTok) {
+ addAsmOperand(String.slice(Prev, i), IsIsolatedToken);
InTok = false;
+ IsIsolatedToken = false;
}
- addAsmOperand(i, i + 1, Separators);
+ addAsmOperand(String.slice(i, i + 1), IsIsolatedToken);
Prev = i + 1;
+ IsIsolatedToken = true;
continue;
}
- if(Variant.SeparatorCharacters.find(String[i]) != std::string::npos) {
- if(InTok) {
- addAsmOperand(Prev, i, Separators);
+ if (Variant.SeparatorCharacters.find(Char) != std::string::npos) {
+ if (InTok) {
+ addAsmOperand(String.slice(Prev, i), IsIsolatedToken);
InTok = false;
}
Prev = i + 1;
+ IsIsolatedToken = true;
continue;
}
- switch (String[i]) {
+
+ switch (Char) {
case '\\':
if (InTok) {
- addAsmOperand(Prev, i, Separators);
+ addAsmOperand(String.slice(Prev, i), false);
InTok = false;
+ IsIsolatedToken = false;
}
++i;
assert(i != String.size() && "Invalid quoted character");
- addAsmOperand(i, i + 1, Separators);
+ addAsmOperand(String.slice(i, i + 1), IsIsolatedToken);
Prev = i + 1;
+ IsIsolatedToken = false;
break;
case '$': {
- if (InTok && Prev != i) {
- addAsmOperand(Prev, i, Separators);
+ if (InTok) {
+ addAsmOperand(String.slice(Prev, i), false);
InTok = false;
+ IsIsolatedToken = false;
}
// If this isn't "${", start new identifier looking like "$xxx"
size_t EndPos = String.find('}', i);
assert(EndPos != StringRef::npos &&
"Missing brace in operand reference!");
- addAsmOperand(i, EndPos+1, Separators);
+ addAsmOperand(String.slice(i, EndPos+1), IsIsolatedToken);
Prev = EndPos + 1;
i = EndPos;
+ IsIsolatedToken = false;
break;
}
+
default:
InTok = true;
+ break;
}
}
if (InTok && Prev != String.size())
- addAsmOperand(Prev, StringRef::npos, Separators);
+ addAsmOperand(String.substr(Prev), IsIsolatedToken);
// The first token of the instruction is the mnemonic, which must be a
// simple string, not a $foo variable or a singleton register.
OS << " if (A == B)\n";
OS << " return true;\n\n";
- std::string OStr;
- raw_string_ostream SS(OStr);
- unsigned Count = 0;
- SS << " switch (A) {\n";
- SS << " default:\n";
- SS << " return false;\n";
+ bool EmittedSwitch = false;
for (const auto &A : Infos) {
std::vector<StringRef> SuperClasses;
for (const auto &B : Infos) {
if (SuperClasses.empty())
continue;
- ++Count;
- SS << "\n case " << A.Name << ":\n";
+ // If this is the first SuperClass, emit the switch header.
+ if (!EmittedSwitch) {
+ OS << " switch (A) {\n";
+ OS << " default:\n";
+ OS << " return false;\n";
+ EmittedSwitch = true;
+ }
+
+ OS << "\n case " << A.Name << ":\n";
if (SuperClasses.size() == 1) {
- SS << " return B == " << SuperClasses.back().str() << ";\n";
+ OS << " return B == " << SuperClasses.back() << ";\n";
continue;
}
if (!SuperClasses.empty()) {
- SS << " switch (B) {\n";
- SS << " default: return false;\n";
+ OS << " switch (B) {\n";
+ OS << " default: return false;\n";
for (StringRef SC : SuperClasses)
- SS << " case " << SC << ": return true;\n";
- SS << " }\n";
+ OS << " case " << SC << ": return true;\n";
+ OS << " }\n";
} else {
// No case statement to emit
- SS << " return false;\n";
+ OS << " return false;\n";
}
}
- SS << " }\n";
+ OS << " }\n";
- // If there were case statements emitted into the string stream, write them
- // to the output stream, otherwise write the default.
- if (Count)
- OS << SS.str();
- else
+ // If there were case statements emitted into the string stream write the
+ // default.
+ if (!EmittedSwitch)
OS << " return false;\n";
OS << "}\n\n";
StringToOffsetTable &StringTable,
unsigned MaxMnemonicIndex) {
unsigned MaxMask = 0;
- for (std::vector<OperandMatchEntry>::const_iterator it =
- Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end();
- it != ie; ++it) {
- MaxMask |= it->OperandMask;
+ for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) {
+ MaxMask |= OMI.OperandMask;
}
// Emit the static custom operand parsing table;
<< Info.OperandMatchInfo.size() << "] = {\n";
OS << " /* Operand List Mask, Mnemonic, Operand Class, Features */\n";
- for (std::vector<OperandMatchEntry>::const_iterator it =
- Info.OperandMatchInfo.begin(), ie = Info.OperandMatchInfo.end();
- it != ie; ++it) {
- const OperandMatchEntry &OMI = *it;
+ for (const OperandMatchEntry &OMI : Info.OperandMatchInfo) {
const MatchableInfo &II = *OMI.MI;
OS << " { ";