mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 06:33:24 +00:00
Revert "Simplify some more ownership using forward_list<T> rather than vector<unique_ptr<T>>"
This reverts commit r222935 and its follow-up r222938 ("Push unique_ptr a bit further through some APIs and simplify some cleanup"), since it causes bot failures (at least on Darwin): http://lab.llvm.org:8080/green/job/clang-stage1-cmake-RA-incremental/1391/ git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@222943 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6e5862cb8c
commit
b60bcfde69
@ -395,10 +395,6 @@ struct MatchableInfo {
|
|||||||
/// matchable came from.
|
/// matchable came from.
|
||||||
Record *const TheDef;
|
Record *const TheDef;
|
||||||
|
|
||||||
/// AsmString - The assembly string for this instruction (with variants
|
|
||||||
/// removed), e.g. "movsx $src, $dst".
|
|
||||||
std::string AsmString;
|
|
||||||
|
|
||||||
/// DefRec - This is the definition that it came from.
|
/// DefRec - This is the definition that it came from.
|
||||||
PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec;
|
PointerUnion<const CodeGenInstruction*, const CodeGenInstAlias*> DefRec;
|
||||||
|
|
||||||
@ -412,6 +408,10 @@ struct MatchableInfo {
|
|||||||
/// MCInst.
|
/// MCInst.
|
||||||
SmallVector<ResOperand, 8> ResOperands;
|
SmallVector<ResOperand, 8> ResOperands;
|
||||||
|
|
||||||
|
/// AsmString - The assembly string for this instruction (with variants
|
||||||
|
/// removed), e.g. "movsx $src, $dst".
|
||||||
|
std::string AsmString;
|
||||||
|
|
||||||
/// Mnemonic - This is the first token of the matched instruction, its
|
/// Mnemonic - This is the first token of the matched instruction, its
|
||||||
/// mnemonic.
|
/// mnemonic.
|
||||||
StringRef Mnemonic;
|
StringRef Mnemonic;
|
||||||
@ -434,14 +434,19 @@ struct MatchableInfo {
|
|||||||
bool HasDeprecation;
|
bool HasDeprecation;
|
||||||
|
|
||||||
MatchableInfo(const CodeGenInstruction &CGI)
|
MatchableInfo(const CodeGenInstruction &CGI)
|
||||||
: AsmVariantID(0), TheDef(CGI.TheDef), AsmString(CGI.AsmString),
|
: AsmVariantID(0), TheDef(CGI.TheDef), DefRec(&CGI),
|
||||||
DefRec(&CGI) {}
|
AsmString(CGI.AsmString) {
|
||||||
|
}
|
||||||
|
|
||||||
MatchableInfo(std::unique_ptr<CodeGenInstAlias> Alias)
|
MatchableInfo(const CodeGenInstAlias *Alias)
|
||||||
: AsmVariantID(0), TheDef(Alias->TheDef), AsmString(Alias->AsmString),
|
: AsmVariantID(0), TheDef(Alias->TheDef), DefRec(Alias),
|
||||||
DefRec(Alias.release()) {}
|
AsmString(Alias->AsmString) {
|
||||||
|
}
|
||||||
|
|
||||||
~MatchableInfo() { delete DefRec.dyn_cast<const CodeGenInstAlias *>(); }
|
~MatchableInfo() {
|
||||||
|
if (DefRec.is<const CodeGenInstAlias*>())
|
||||||
|
delete DefRec.get<const CodeGenInstAlias*>();
|
||||||
|
}
|
||||||
|
|
||||||
// Two-operand aliases clone from the main matchable, but mark the second
|
// Two-operand aliases clone from the main matchable, but mark the second
|
||||||
// operand as a tied operand of the first for purposes of the assembler.
|
// operand as a tied operand of the first for purposes of the assembler.
|
||||||
@ -611,7 +616,7 @@ public:
|
|||||||
std::forward_list<ClassInfo> Classes;
|
std::forward_list<ClassInfo> Classes;
|
||||||
|
|
||||||
/// The information on the matchables to match.
|
/// The information on the matchables to match.
|
||||||
std::forward_list<MatchableInfo> Matchables;
|
std::vector<std::unique_ptr<MatchableInfo>> Matchables;
|
||||||
|
|
||||||
/// Info for custom matching operands by user defined methods.
|
/// Info for custom matching operands by user defined methods.
|
||||||
std::vector<OperandMatchEntry> OperandMatchInfo;
|
std::vector<OperandMatchEntry> OperandMatchInfo;
|
||||||
@ -1279,8 +1284,8 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
|
|||||||
|
|
||||||
// Keep track of all operands of this instructions which belong to the
|
// Keep track of all operands of this instructions which belong to the
|
||||||
// same class.
|
// same class.
|
||||||
for (unsigned i = 0, e = MI.AsmOperands.size(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
|
||||||
const MatchableInfo::AsmOperand &Op = MI.AsmOperands[i];
|
const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i];
|
||||||
if (Op.Class->ParserMethod.empty())
|
if (Op.Class->ParserMethod.empty())
|
||||||
continue;
|
continue;
|
||||||
unsigned &OperandMask = OpClassMask[Op.Class];
|
unsigned &OperandMask = OpClassMask[Op.Class];
|
||||||
@ -1291,7 +1296,8 @@ void AsmMatcherInfo::buildOperandMatchInfo() {
|
|||||||
for (const auto &OCM : OpClassMask) {
|
for (const auto &OCM : OpClassMask) {
|
||||||
unsigned OpMask = OCM.second;
|
unsigned OpMask = OCM.second;
|
||||||
ClassInfo *CI = OCM.first;
|
ClassInfo *CI = OCM.first;
|
||||||
OperandMatchInfo.push_back(OperandMatchEntry::create(&MI, CI, OpMask));
|
OperandMatchInfo.push_back(OperandMatchEntry::create(MI.get(), CI,
|
||||||
|
OpMask));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1337,15 +1343,16 @@ void AsmMatcherInfo::buildInfo() {
|
|||||||
if (CGI->TheDef->getValueAsBit("isCodeGenOnly"))
|
if (CGI->TheDef->getValueAsBit("isCodeGenOnly"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Matchables.emplace_front(*CGI);
|
std::unique_ptr<MatchableInfo> II(new MatchableInfo(*CGI));
|
||||||
MatchableInfo *II = &Matchables.front();
|
|
||||||
|
|
||||||
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
|
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
|
||||||
|
|
||||||
// Ignore instructions which shouldn't be matched and diagnose invalid
|
// Ignore instructions which shouldn't be matched and diagnose invalid
|
||||||
// instruction definitions with an error.
|
// instruction definitions with an error.
|
||||||
if (!II->validate(CommentDelimiter, true))
|
if (!II->validate(CommentDelimiter, true))
|
||||||
Matchables.pop_front();
|
continue;
|
||||||
|
|
||||||
|
Matchables.push_back(std::move(II));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse all of the InstAlias definitions and stick them in the list of
|
// Parse all of the InstAlias definitions and stick them in the list of
|
||||||
@ -1353,8 +1360,8 @@ void AsmMatcherInfo::buildInfo() {
|
|||||||
std::vector<Record*> AllInstAliases =
|
std::vector<Record*> AllInstAliases =
|
||||||
Records.getAllDerivedDefinitions("InstAlias");
|
Records.getAllDerivedDefinitions("InstAlias");
|
||||||
for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
|
for (unsigned i = 0, e = AllInstAliases.size(); i != e; ++i) {
|
||||||
auto Alias = llvm::make_unique<CodeGenInstAlias>(AllInstAliases[i],
|
CodeGenInstAlias *Alias =
|
||||||
AsmVariantNo, Target);
|
new CodeGenInstAlias(AllInstAliases[i], AsmVariantNo, Target);
|
||||||
|
|
||||||
// If the tblgen -match-prefix option is specified (for tblgen hackers),
|
// If the tblgen -match-prefix option is specified (for tblgen hackers),
|
||||||
// filter the set of instruction aliases we consider, based on the target
|
// filter the set of instruction aliases we consider, based on the target
|
||||||
@ -1363,13 +1370,14 @@ void AsmMatcherInfo::buildInfo() {
|
|||||||
.startswith( MatchPrefix))
|
.startswith( MatchPrefix))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Matchables.emplace_front(std::move(Alias));
|
std::unique_ptr<MatchableInfo> II(new MatchableInfo(Alias));
|
||||||
MatchableInfo *II = &Matchables.front();
|
|
||||||
|
|
||||||
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
|
II->initialize(*this, SingletonRegisters, AsmVariantNo, RegisterPrefix);
|
||||||
|
|
||||||
// Validate the alias definitions.
|
// Validate the alias definitions.
|
||||||
II->validate(CommentDelimiter, false);
|
II->validate(CommentDelimiter, false);
|
||||||
|
|
||||||
|
Matchables.push_back(std::move(II));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1381,17 +1389,17 @@ void AsmMatcherInfo::buildInfo() {
|
|||||||
|
|
||||||
// Build the information about matchables, now that we have fully formed
|
// Build the information about matchables, now that we have fully formed
|
||||||
// classes.
|
// classes.
|
||||||
std::forward_list<MatchableInfo> NewMatchables;
|
std::vector<std::unique_ptr<MatchableInfo>> NewMatchables;
|
||||||
for (auto &II : Matchables) {
|
for (auto &II : Matchables) {
|
||||||
// Parse the tokens after the mnemonic.
|
// Parse the tokens after the mnemonic.
|
||||||
// Note: buildInstructionOperandReference may insert new AsmOperands, so
|
// Note: buildInstructionOperandReference may insert new AsmOperands, so
|
||||||
// don't precompute the loop bound.
|
// don't precompute the loop bound.
|
||||||
for (unsigned i = 0; i != II.AsmOperands.size(); ++i) {
|
for (unsigned i = 0; i != II->AsmOperands.size(); ++i) {
|
||||||
MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
|
MatchableInfo::AsmOperand &Op = II->AsmOperands[i];
|
||||||
StringRef Token = Op.Token;
|
StringRef Token = Op.Token;
|
||||||
|
|
||||||
// Check for singleton registers.
|
// Check for singleton registers.
|
||||||
if (Record *RegRecord = II.AsmOperands[i].SingletonReg) {
|
if (Record *RegRecord = II->AsmOperands[i].SingletonReg) {
|
||||||
Op.Class = RegisterClasses[RegRecord];
|
Op.Class = RegisterClasses[RegRecord];
|
||||||
assert(Op.Class && Op.Class->Registers.size() == 1 &&
|
assert(Op.Class && Op.Class->Registers.size() == 1 &&
|
||||||
"Unexpected class for singleton register");
|
"Unexpected class for singleton register");
|
||||||
@ -1416,30 +1424,35 @@ void AsmMatcherInfo::buildInfo() {
|
|||||||
else
|
else
|
||||||
OperandName = Token.substr(1);
|
OperandName = Token.substr(1);
|
||||||
|
|
||||||
if (II.DefRec.is<const CodeGenInstruction *>())
|
if (II->DefRec.is<const CodeGenInstruction*>())
|
||||||
buildInstructionOperandReference(&II, OperandName, i);
|
buildInstructionOperandReference(II.get(), OperandName, i);
|
||||||
else
|
else
|
||||||
buildAliasOperandReference(&II, OperandName, Op);
|
buildAliasOperandReference(II.get(), OperandName, Op);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (II.DefRec.is<const CodeGenInstruction *>()) {
|
if (II->DefRec.is<const CodeGenInstruction*>()) {
|
||||||
II.buildInstructionResultOperands();
|
II->buildInstructionResultOperands();
|
||||||
// If the instruction has a two-operand alias, build up the
|
// If the instruction has a two-operand alias, build up the
|
||||||
// matchable here. We'll add them in bulk at the end to avoid
|
// matchable here. We'll add them in bulk at the end to avoid
|
||||||
// confusing this loop.
|
// confusing this loop.
|
||||||
std::string Constraint =
|
std::string Constraint =
|
||||||
II.TheDef->getValueAsString("TwoOperandAliasConstraint");
|
II->TheDef->getValueAsString("TwoOperandAliasConstraint");
|
||||||
if (Constraint != "") {
|
if (Constraint != "") {
|
||||||
// Start by making a copy of the original matchable.
|
// Start by making a copy of the original matchable.
|
||||||
NewMatchables.emplace_front(II);
|
std::unique_ptr<MatchableInfo> AliasII(new MatchableInfo(*II));
|
||||||
|
|
||||||
// Adjust it to be a two-operand alias.
|
// Adjust it to be a two-operand alias.
|
||||||
NewMatchables.front().formTwoOperandAlias(Constraint);
|
AliasII->formTwoOperandAlias(Constraint);
|
||||||
|
|
||||||
|
// Add the alias to the matchables list.
|
||||||
|
NewMatchables.push_back(std::move(AliasII));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
II.buildAliasResultOperands();
|
II->buildAliasResultOperands();
|
||||||
}
|
}
|
||||||
Matchables.splice_after(Matchables.before_begin(), NewMatchables);
|
if (!NewMatchables.empty())
|
||||||
|
std::move(NewMatchables.begin(), NewMatchables.end(),
|
||||||
|
std::back_inserter(Matchables));
|
||||||
|
|
||||||
// Process token alias definitions and set up the associated superclass
|
// Process token alias definitions and set up the associated superclass
|
||||||
// information.
|
// information.
|
||||||
@ -1664,8 +1677,9 @@ static unsigned getConverterOperandID(const std::string &Name,
|
|||||||
return ID;
|
return ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||||
std::forward_list<MatchableInfo> &Infos,
|
std::vector<std::unique_ptr<MatchableInfo>> &Infos,
|
||||||
raw_ostream &OS) {
|
raw_ostream &OS) {
|
||||||
SetVector<std::string> OperandConversionKinds;
|
SetVector<std::string> OperandConversionKinds;
|
||||||
SetVector<std::string> InstructionConversionKinds;
|
SetVector<std::string> InstructionConversionKinds;
|
||||||
@ -1732,10 +1746,10 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
|||||||
for (auto &II : Infos) {
|
for (auto &II : Infos) {
|
||||||
// Check if we have a custom match function.
|
// Check if we have a custom match function.
|
||||||
std::string AsmMatchConverter =
|
std::string AsmMatchConverter =
|
||||||
II.getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
|
II->getResultInst()->TheDef->getValueAsString("AsmMatchConverter");
|
||||||
if (!AsmMatchConverter.empty()) {
|
if (!AsmMatchConverter.empty()) {
|
||||||
std::string Signature = "ConvertCustom_" + AsmMatchConverter;
|
std::string Signature = "ConvertCustom_" + AsmMatchConverter;
|
||||||
II.ConversionFnKind = Signature;
|
II->ConversionFnKind = Signature;
|
||||||
|
|
||||||
// Check if we have already generated this signature.
|
// Check if we have already generated this signature.
|
||||||
if (!InstructionConversionKinds.insert(Signature))
|
if (!InstructionConversionKinds.insert(Signature))
|
||||||
@ -1767,17 +1781,17 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
|||||||
std::vector<uint8_t> ConversionRow;
|
std::vector<uint8_t> ConversionRow;
|
||||||
|
|
||||||
// Compute the convert enum and the case body.
|
// Compute the convert enum and the case body.
|
||||||
MaxRowLength = std::max(MaxRowLength, II.ResOperands.size() * 2 + 1);
|
MaxRowLength = std::max(MaxRowLength, II->ResOperands.size()*2 + 1 );
|
||||||
|
|
||||||
for (unsigned i = 0, e = II.ResOperands.size(); i != e; ++i) {
|
for (unsigned i = 0, e = II->ResOperands.size(); i != e; ++i) {
|
||||||
const MatchableInfo::ResOperand &OpInfo = II.ResOperands[i];
|
const MatchableInfo::ResOperand &OpInfo = II->ResOperands[i];
|
||||||
|
|
||||||
// Generate code to populate each result operand.
|
// Generate code to populate each result operand.
|
||||||
switch (OpInfo.Kind) {
|
switch (OpInfo.Kind) {
|
||||||
case MatchableInfo::ResOperand::RenderAsmOperand: {
|
case MatchableInfo::ResOperand::RenderAsmOperand: {
|
||||||
// This comes from something we parsed.
|
// This comes from something we parsed.
|
||||||
const MatchableInfo::AsmOperand &Op =
|
const MatchableInfo::AsmOperand &Op =
|
||||||
II.AsmOperands[OpInfo.AsmOperandNum];
|
II->AsmOperands[OpInfo.AsmOperandNum];
|
||||||
|
|
||||||
// Registers are always converted the same, don't duplicate the
|
// Registers are always converted the same, don't duplicate the
|
||||||
// conversion function based on them.
|
// conversion function based on them.
|
||||||
@ -1900,7 +1914,7 @@ static void emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
|||||||
if (Signature == "Convert")
|
if (Signature == "Convert")
|
||||||
Signature += "_NoOperands";
|
Signature += "_NoOperands";
|
||||||
|
|
||||||
II.ConversionFnKind = Signature;
|
II->ConversionFnKind = Signature;
|
||||||
|
|
||||||
// Save the signature. If we already have it, don't add a new row
|
// Save the signature. If we already have it, don't add a new row
|
||||||
// to the table.
|
// to the table.
|
||||||
@ -2586,21 +2600,23 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
// Sort the instruction table using the partial order on classes. We use
|
// Sort the instruction table using the partial order on classes. We use
|
||||||
// stable_sort to ensure that ambiguous instructions are still
|
// stable_sort to ensure that ambiguous instructions are still
|
||||||
// deterministically ordered.
|
// deterministically ordered.
|
||||||
Info.Matchables.sort();
|
std::stable_sort(Info.Matchables.begin(), Info.Matchables.end(),
|
||||||
|
[](const std::unique_ptr<MatchableInfo> &a,
|
||||||
|
const std::unique_ptr<MatchableInfo> &b){
|
||||||
|
return *a < *b;});
|
||||||
|
|
||||||
DEBUG_WITH_TYPE("instruction_info", {
|
DEBUG_WITH_TYPE("instruction_info", {
|
||||||
for (const auto &MI : Info.Matchables)
|
for (const auto &MI : Info.Matchables)
|
||||||
MI.dump();
|
MI->dump();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check for ambiguous matchables.
|
// Check for ambiguous matchables.
|
||||||
DEBUG_WITH_TYPE("ambiguous_instrs", {
|
DEBUG_WITH_TYPE("ambiguous_instrs", {
|
||||||
unsigned NumAmbiguous = 0;
|
unsigned NumAmbiguous = 0;
|
||||||
for (auto I = Info.Matchables.begin(), E = Info.Matchables.end(); I != E;
|
for (unsigned i = 0, e = Info.Matchables.size(); i != e; ++i) {
|
||||||
++I) {
|
for (unsigned j = i + 1; j != e; ++j) {
|
||||||
for (auto J = std::next(I); J != E; ++J) {
|
const MatchableInfo &A = *Info.Matchables[i];
|
||||||
const MatchableInfo &A = *I;
|
const MatchableInfo &B = *Info.Matchables[j];
|
||||||
const MatchableInfo &B = *J;
|
|
||||||
|
|
||||||
if (A.couldMatchAmbiguouslyWith(B)) {
|
if (A.couldMatchAmbiguouslyWith(B)) {
|
||||||
errs() << "warning: ambiguous matchables:\n";
|
errs() << "warning: ambiguous matchables:\n";
|
||||||
@ -2721,11 +2737,11 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
unsigned MaxMnemonicIndex = 0;
|
unsigned MaxMnemonicIndex = 0;
|
||||||
bool HasDeprecation = false;
|
bool HasDeprecation = false;
|
||||||
for (const auto &MI : Info.Matchables) {
|
for (const auto &MI : Info.Matchables) {
|
||||||
MaxNumOperands = std::max(MaxNumOperands, MI.AsmOperands.size());
|
MaxNumOperands = std::max(MaxNumOperands, MI->AsmOperands.size());
|
||||||
HasDeprecation |= MI.HasDeprecation;
|
HasDeprecation |= MI->HasDeprecation;
|
||||||
|
|
||||||
// Store a pascal-style length byte in the mnemonic.
|
// Store a pascal-style length byte in the mnemonic.
|
||||||
std::string LenMnemonic = char(MI.Mnemonic.size()) + MI.Mnemonic.str();
|
std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str();
|
||||||
MaxMnemonicIndex = std::max(MaxMnemonicIndex,
|
MaxMnemonicIndex = std::max(MaxMnemonicIndex,
|
||||||
StringTable.GetOrAddStringOffset(LenMnemonic, false));
|
StringTable.GetOrAddStringOffset(LenMnemonic, false));
|
||||||
}
|
}
|
||||||
@ -2749,8 +2765,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
OS << " " << getMinimalTypeForRange(MaxMnemonicIndex)
|
OS << " " << getMinimalTypeForRange(MaxMnemonicIndex)
|
||||||
<< " Mnemonic;\n";
|
<< " Mnemonic;\n";
|
||||||
OS << " uint16_t Opcode;\n";
|
OS << " uint16_t Opcode;\n";
|
||||||
OS << " " << getMinimalTypeForRange(std::distance(Info.Matchables.begin(),
|
OS << " " << getMinimalTypeForRange(Info.Matchables.size())
|
||||||
Info.Matchables.end()))
|
|
||||||
<< " ConvertFn;\n";
|
<< " ConvertFn;\n";
|
||||||
OS << " " << getMinimalRequiredFeaturesType(Info)
|
OS << " " << getMinimalRequiredFeaturesType(Info)
|
||||||
<< " RequiredFeatures;\n";
|
<< " RequiredFeatures;\n";
|
||||||
@ -2786,28 +2801,29 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
|
OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
|
||||||
|
|
||||||
for (const auto &MI : Info.Matchables) {
|
for (const auto &MI : Info.Matchables) {
|
||||||
if (MI.AsmVariantID != AsmVariantNo)
|
if (MI->AsmVariantID != AsmVariantNo)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Store a pascal-style length byte in the mnemonic.
|
// Store a pascal-style length byte in the mnemonic.
|
||||||
std::string LenMnemonic = char(MI.Mnemonic.size()) + MI.Mnemonic.str();
|
std::string LenMnemonic = char(MI->Mnemonic.size()) + MI->Mnemonic.str();
|
||||||
OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
|
OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
|
||||||
<< " /* " << MI.Mnemonic << " */, " << Target.getName()
|
<< " /* " << MI->Mnemonic << " */, "
|
||||||
<< "::" << MI.getResultInst()->TheDef->getName() << ", "
|
<< Target.getName() << "::"
|
||||||
<< MI.ConversionFnKind << ", ";
|
<< MI->getResultInst()->TheDef->getName() << ", "
|
||||||
|
<< MI->ConversionFnKind << ", ";
|
||||||
|
|
||||||
// Write the required features mask.
|
// Write the required features mask.
|
||||||
if (!MI.RequiredFeatures.empty()) {
|
if (!MI->RequiredFeatures.empty()) {
|
||||||
for (unsigned i = 0, e = MI.RequiredFeatures.size(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->RequiredFeatures.size(); i != e; ++i) {
|
||||||
if (i) OS << "|";
|
if (i) OS << "|";
|
||||||
OS << MI.RequiredFeatures[i]->getEnumName();
|
OS << MI->RequiredFeatures[i]->getEnumName();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
OS << "0";
|
OS << "0";
|
||||||
|
|
||||||
OS << ", { ";
|
OS << ", { ";
|
||||||
for (unsigned i = 0, e = MI.AsmOperands.size(); i != e; ++i) {
|
for (unsigned i = 0, e = MI->AsmOperands.size(); i != e; ++i) {
|
||||||
const MatchableInfo::AsmOperand &Op = MI.AsmOperands[i];
|
const MatchableInfo::AsmOperand &Op = MI->AsmOperands[i];
|
||||||
|
|
||||||
if (i) OS << ", ";
|
if (i) OS << ", ";
|
||||||
OS << Op.Class->Name;
|
OS << Op.Class->Name;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user