TheDef->getValueAsBit("UseInstAsmMatchConverter")) {
}
+ // Could remove this and the dtor if PointerUnion supported unique_ptr
+ // elements with a dynamic failure/assertion (like the one below) in the case
+ // where it was copied while being in an owning state.
+ MatchableInfo(const MatchableInfo &RHS)
+ : AsmVariantID(RHS.AsmVariantID), AsmString(RHS.AsmString),
+ TheDef(RHS.TheDef), DefRec(RHS.DefRec), ResOperands(RHS.ResOperands),
+ Mnemonic(RHS.Mnemonic), AsmOperands(RHS.AsmOperands),
+ RequiredFeatures(RHS.RequiredFeatures),
+ ConversionFnKind(RHS.ConversionFnKind),
+ HasDeprecation(RHS.HasDeprecation),
+ UseInstAsmMatchConverter(RHS.UseInstAsmMatchConverter) {
+ assert(!DefRec.is<const CodeGenInstAlias *>());
+ }
+
~MatchableInfo() {
delete DefRec.dyn_cast<const CodeGenInstAlias*>();
}
void initialize(const AsmMatcherInfo &Info,
SmallPtrSetImpl<Record*> &SingletonRegisters,
- int AsmVariantNo, std::string &RegisterPrefix);
+ int AsmVariantNo, StringRef 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;
- /// 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.
int findAsmOperand(StringRef N, int SubOpIdx) const {
}
}
+/// extractSingletonRegisterForAsmOperand - Extract singleton register,
+/// if present, from specified token.
+static void
+extractSingletonRegisterForAsmOperand(MatchableInfo::AsmOperand &Op,
+ const AsmMatcherInfo &Info,
+ StringRef RegisterPrefix) {
+ StringRef Tok = Op.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 (!Op.IsIsolatedToken)
+ return;
+
+ if (RegisterPrefix.empty()) {
+ std::string LoweredTok = Tok.lower();
+ if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(LoweredTok))
+ Op.SingletonReg = Reg->TheDef;
+ return;
+ }
+
+ if (!Tok.startswith(RegisterPrefix))
+ return;
+
+ StringRef RegName = Tok.substr(RegisterPrefix.size());
+ if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName))
+ Op.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.
+ return;
+}
+
void MatchableInfo::initialize(const AsmMatcherInfo &Info,
SmallPtrSetImpl<Record*> &SingletonRegisters,
- int AsmVariantNo, std::string &RegisterPrefix) {
+ int AsmVariantNo, StringRef RegisterPrefix) {
AsmVariantID = AsmVariantNo;
AsmString =
CodeGenInstruction::FlattenAsmStringVariants(AsmString, AsmVariantNo);
tokenizeAsmString(Info);
// Compute the require features.
- std::vector<Record*> Predicates =TheDef->getValueAsListOfDefs("Predicates");
- for (unsigned i = 0, e = Predicates.size(); i != e; ++i)
+ for (Record *Predicate : TheDef->getValueAsListOfDefs("Predicates"))
if (const SubtargetFeatureInfo *Feature =
- Info.getSubtargetFeature(Predicates[i]))
+ Info.getSubtargetFeature(Predicate))
RequiredFeatures.push_back(Feature);
// Collect singleton registers, if used.
- for (unsigned i = 0, e = AsmOperands.size(); i != e; ++i) {
- extractSingletonRegisterForAsmOperand(i, Info, RegisterPrefix);
- if (Record *Reg = AsmOperands[i].SingletonReg)
+ for (MatchableInfo::AsmOperand &Op : AsmOperands) {
+ extractSingletonRegisterForAsmOperand(Op, Info, RegisterPrefix);
+ if (Record *Reg = Op.SingletonReg)
SingletonRegisters.insert(Reg);
}
/// tokenizeAsmString - Tokenize a simplified assembly string.
void MatchableInfo::tokenizeAsmString(const AsmMatcherInfo &Info) {
StringRef String = AsmString;
- unsigned Prev = 0;
+ size_t Prev = 0;
bool InTok = true;
- for (unsigned i = 0, e = String.size(); i != e; ++i) {
+ for (size_t i = 0, e = String.size(); i != e; ++i) {
switch (String[i]) {
case '[':
case ']':
InTok = false;
}
- // If this isn't "${", treat like a normal token.
+ // If this isn't "${", start new identifier looking like "$xxx"
if (i + 1 == String.size() || String[i + 1] != '{') {
Prev = i;
break;
}
- 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();
+ // If this is "${" find the next "}" and make an identifier like "${xxx}"
+ size_t EndPos = String.find('}', i);
+ assert(EndPos != StringRef::npos &&
+ "Missing brace in operand reference!");
addAsmOperand(i, EndPos+1);
Prev = EndPos + 1;
i = EndPos;
return true;
}
-/// extractSingletonRegisterForAsmOperand - Extract singleton register,
-/// if present, from specified token.
-void MatchableInfo::
-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))
- AsmOperands[OperandNo].SingletonReg = Reg->TheDef;
- return;
- }
-
- if (!Tok.startswith(RegisterPrefix))
- return;
-
- StringRef RegName = Tok.substr(RegisterPrefix.size());
- if (const CodeGenRegister *Reg = Info.Target.getRegisterByName(RegName))
- AsmOperands[OperandNo].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.
- return;
-}
-
static std::string getEnumNameForToken(StringRef Str) {
std::string Res;
if (CGI->TheDef->getValueAsBit("isCodeGenOnly"))
continue;
- std::unique_ptr<MatchableInfo> II(new MatchableInfo(*CGI));
+ auto II = llvm::make_unique<MatchableInfo>(*CGI);
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
.startswith( MatchPrefix))
continue;
- std::unique_ptr<MatchableInfo> II(new MatchableInfo(std::move(Alias)));
+ auto II = llvm::make_unique<MatchableInfo>(std::move(Alias));
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
II->TheDef->getValueAsString("TwoOperandAliasConstraint");
if (Constraint != "") {
// Start by making a copy of the original matchable.
- std::unique_ptr<MatchableInfo> AliasII(new MatchableInfo(*II));
+ auto AliasII = llvm::make_unique<MatchableInfo>(*II);
// Adjust it to be a two-operand alias.
AliasII->formTwoOperandAlias(Constraint);
continue;
// Add the row to the table.
- ConversionTable.push_back(ConversionRow);
+ ConversionTable.push_back(std::move(ConversionRow));
}
// Finish up the converter driver function.
// Output the instruction conversion kind enum.
OS << "enum InstructionConversionKind {\n";
- for (SetVector<std::string>::const_iterator
- i = InstructionConversionKinds.begin(),
- e = InstructionConversionKinds.end(); i != e; ++i)
- OS << " " << *i << ",\n";
+ for (const std::string &Signature : InstructionConversionKinds)
+ OS << " " << Signature << ",\n";
OS << " CVT_NUM_SIGNATURES\n";
OS << "};\n\n";
<< " {\n";
for (const auto &SF : Info.SubtargetFeatures) {
const SubtargetFeatureInfo &SFI = SF.second;
- OS << " " << SFI.getEnumName() << " = " << SFI.Index << ",\n";
+ OS << " " << SFI.getEnumName() << " = (1ULL << " << SFI.Index << "),\n";
}
OS << " Feature_None = 0\n";
OS << "};\n\n";
static void emitGetSubtargetFeatureName(AsmMatcherInfo &Info, raw_ostream &OS) {
OS << "// User-level names for subtarget features that participate in\n"
<< "// instruction matching.\n"
- << "static const char *getSubtargetFeatureName(uint64_t Feature) {\n";
+ << "static const char *getSubtargetFeatureName(uint64_t Val) {\n";
if (!Info.SubtargetFeatures.empty()) {
- OS << " switch(Feature) {\n";
+ OS << " switch(Val) {\n";
for (const auto &SF : Info.SubtargetFeatures) {
const SubtargetFeatureInfo &SFI = SF.second;
// FIXME: Totally just a placeholder name to get the algorithm working.
std::string ClassName =
Info.AsmParser->getValueAsString("AsmParserClassName");
- OS << "FeatureBitset " << Info.Target.getName() << ClassName << "::\n"
+ OS << "uint64_t " << Info.Target.getName() << ClassName << "::\n"
<< "ComputeAvailableFeatures(const FeatureBitset& FB) const {\n";
- OS << " FeatureBitset Features;\n";
+ OS << " uint64_t Features = 0;\n";
for (const auto &SF : Info.SubtargetFeatures) {
const SubtargetFeatureInfo &SFI = SF.second;
} while (true);
OS << ")\n";
- OS << " Features.set(" << SFI.getEnumName() << ", 1);\n";
+ OS << " Features |= " << SFI.getEnumName() << ";\n";
}
OS << " return Features;\n";
OS << "}\n\n";
if (!MatchCode.empty())
MatchCode += "else ";
- MatchCode += "if ((Features & FeatureBitset({"+FeatureMask+"})) == FeatureBitset({"+FeatureMask+"}))\n";
+ MatchCode += "if ((Features & " + FeatureMask + ") == "+FeatureMask+")\n";
MatchCode += " Mnemonic = \"" +R->getValueAsString("ToMnemonic")+"\";\n";
}
if (Aliases.empty()) return false;
OS << "static void applyMnemonicAliases(StringRef &Mnemonic, "
- "FeatureBitset Features, unsigned VariantID) {\n";
+ "uint64_t Features, unsigned VariantID) {\n";
OS << " switch (VariantID) {\n";
unsigned VariantCount = Target.getAsmParserVariantCount();
for (unsigned VC = 0; VC != VariantCount; ++VC) {
// Emit the static custom operand parsing table;
OS << "namespace {\n";
OS << " struct OperandMatchEntry {\n";
- OS << " FeatureBitset RequiredFeatures;\n";
+ OS << " " << getMinimalRequiredFeaturesType(Info)
+ << " RequiredFeatures;\n";
OS << " " << getMinimalTypeForRange(MaxMnemonicIndex)
<< " Mnemonic;\n";
OS << " " << getMinimalTypeForRange(std::distance(
// Write the required features mask.
if (!II.RequiredFeatures.empty()) {
- OS << "{";
for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
- if (i) OS << ",";
+ if (i) OS << "|";
OS << II.RequiredFeatures[i]->getEnumName();
}
- OS << "}";
} else
- OS << "{}";
+ OS << "0";
// Store a pascal-style length byte in the mnemonic.
std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
// Emit code to get the available features.
OS << " // Get the current feature set.\n";
- OS << " FeatureBitset AvailableFeatures = getAvailableFeatures();\n\n";
+ OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
OS << " // Get the next operand index.\n";
OS << " unsigned NextOpNum = Operands.size()-1;\n";
OS << "#undef GET_ASSEMBLER_HEADER\n";
OS << " // This should be included into the middle of the declaration of\n";
OS << " // your subclasses implementation of MCTargetAsmParser.\n";
- OS << " FeatureBitset ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
+ OS << " uint64_t ComputeAvailableFeatures(const FeatureBitset& FB) const;\n";
OS << " void convertToMCInst(unsigned Kind, MCInst &Inst, "
<< "unsigned Opcode,\n"
<< " const OperandVector "
OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) override;\n";
OS << " unsigned MatchInstructionImpl(const OperandVector &Operands,\n"
<< " MCInst &Inst,\n"
- << " uint64_t &ErrorInfo,\n"
- << " FeatureBitset &ErrorMissingFeature,\n"
- << " bool matchingInlineAsm,\n"
+ << " uint64_t &ErrorInfo,"
+ << " bool matchingInlineAsm,\n"
<< " unsigned VariantID = 0);\n";
if (!Info.OperandMatchInfo.empty()) {
OS << " uint16_t Opcode;\n";
OS << " " << getMinimalTypeForRange(Info.Matchables.size())
<< " ConvertFn;\n";
- OS << " FeatureBitset RequiredFeatures;\n";
+ OS << " " << getMinimalRequiredFeaturesType(Info)
+ << " RequiredFeatures;\n";
OS << " " << getMinimalTypeForRange(
std::distance(Info.Classes.begin(), Info.Classes.end()))
<< " Classes[" << MaxNumOperands << "];\n";
// Write the required features mask.
if (!MI->RequiredFeatures.empty()) {
- OS << "{";
for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) {
- if (i) OS << ",";
+ if (i) OS << "|";
OS << MI->RequiredFeatures[i]->getEnumName();
}
- OS << "}";
} else
- OS << "{}";
+ OS << "0";
OS << ", { ";
for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
OS << "unsigned " << Target.getName() << ClassName << "::\n"
<< "MatchInstructionImpl(const OperandVector &Operands,\n";
OS << " MCInst &Inst, uint64_t &ErrorInfo,\n"
- << " FeatureBitset &ErrorMissingFeature,\n"
<< " bool matchingInlineAsm, unsigned VariantID) {\n";
OS << " // Eliminate obvious mismatches.\n";
// Emit code to get the available features.
OS << " // Get the current feature set.\n";
- OS << " FeatureBitset AvailableFeatures = getAvailableFeatures();\n\n";
+ OS << " uint64_t AvailableFeatures = getAvailableFeatures();\n\n";
OS << " // Get the instruction mnemonic, which is the first token.\n";
OS << " StringRef Mnemonic = ((" << Target.getName()
OS << " bool HadMatchOtherThanFeatures = false;\n";
OS << " bool HadMatchOtherThanPredicate = false;\n";
OS << " unsigned RetCode = Match_InvalidOperand;\n";
- OS << " FeatureBitset MissingFeatures(~0ULL);\n";
+ OS << " uint64_t MissingFeatures = ~0ULL;\n";
OS << " // Set ErrorInfo to the operand that mismatches if it is\n";
OS << " // wrong for all instances of the instruction.\n";
OS << " ErrorInfo = ~0ULL;\n";
OS << " if ((AvailableFeatures & it->RequiredFeatures) "
<< "!= it->RequiredFeatures) {\n";
OS << " HadMatchOtherThanFeatures = true;\n";
- OS << " FeatureBitset NewMissingFeatures = it->RequiredFeatures & "
+ OS << " uint64_t NewMissingFeatures = it->RequiredFeatures & "
"~AvailableFeatures;\n";
- OS << " if (NewMissingFeatures.count() <=\n"
- " MissingFeatures.count())\n";
+ OS << " if (countPopulation(NewMissingFeatures) <=\n"
+ " countPopulation(MissingFeatures))\n";
OS << " MissingFeatures = NewMissingFeatures;\n";
OS << " continue;\n";
OS << " }\n";
OS << " if (HadMatchOtherThanPredicate || !HadMatchOtherThanFeatures)\n";
OS << " return RetCode;\n\n";
OS << " // Missing feature matches return which features were missing\n";
- OS << " ErrorMissingFeature = MissingFeatures;\n";
+ OS << " ErrorInfo = MissingFeatures;\n";
OS << " return Match_MissingFeature;\n";
OS << "}\n\n";