mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-25 16:24:23 +00:00
Split generated asm mnemonic matching table into a separate table for each asm variant.
This removes the need to store the asm variant in each row of the single table that existed before. Shaves ~16K off the size of X86AsmParser.o. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187026 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -143,7 +143,7 @@ public:
|
|||||||
|
|
||||||
/// mnemonicIsValid - This returns true if this is a valid mnemonic and false
|
/// mnemonicIsValid - This returns true if this is a valid mnemonic and false
|
||||||
/// otherwise.
|
/// otherwise.
|
||||||
virtual bool mnemonicIsValid(StringRef Mnemonic) = 0;
|
virtual bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) = 0;
|
||||||
|
|
||||||
/// MatchAndEmitInstruction - Recognize a series of operands of a parsed
|
/// MatchAndEmitInstruction - Recognize a series of operands of a parsed
|
||||||
/// instruction as an actual MCInst and emit it to the specified MCStreamer.
|
/// instruction as an actual MCInst and emit it to the specified MCStreamer.
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "MCTargetDesc/MBlazeBaseInfo.h"
|
#include "MCTargetDesc/MBlazeBaseInfo.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/Twine.h"
|
#include "llvm/ADT/Twine.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
|
@ -1501,7 +1501,7 @@ bool MipsAsmParser::
|
|||||||
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
|
||||||
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
|
||||||
// Check if we have valid mnemonic
|
// Check if we have valid mnemonic
|
||||||
if (!mnemonicIsValid(Name)) {
|
if (!mnemonicIsValid(Name, 0)) {
|
||||||
Parser.eatToEndOfStatement();
|
Parser.eatToEndOfStatement();
|
||||||
return Error(NameLoc, "Unknown instruction");
|
return Error(NameLoc, "Unknown instruction");
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||||
#include "llvm/MC/MCParser/MCAsmParser.h"
|
#include "llvm/MC/MCParser/MCAsmParser.h"
|
||||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "MCTargetDesc/SystemZMCTargetDesc.h"
|
#include "MCTargetDesc/SystemZMCTargetDesc.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/MC/MCContext.h"
|
#include "llvm/MC/MCContext.h"
|
||||||
#include "llvm/MC/MCExpr.h"
|
#include "llvm/MC/MCExpr.h"
|
||||||
#include "llvm/MC/MCInst.h"
|
#include "llvm/MC/MCInst.h"
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "MCTargetDesc/X86BaseInfo.h"
|
#include "MCTargetDesc/X86BaseInfo.h"
|
||||||
#include "llvm/ADT/APFloat.h"
|
#include "llvm/ADT/APFloat.h"
|
||||||
|
#include "llvm/ADT/STLExtras.h"
|
||||||
#include "llvm/ADT/SmallString.h"
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/SmallVector.h"
|
#include "llvm/ADT/SmallVector.h"
|
||||||
#include "llvm/ADT/StringSwitch.h"
|
#include "llvm/ADT/StringSwitch.h"
|
||||||
|
@ -2658,7 +2658,7 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
<< "&Operands);\n";
|
<< "&Operands);\n";
|
||||||
OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
|
OS << " void convertToMapAndConstraints(unsigned Kind,\n ";
|
||||||
OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands);\n";
|
OS << " const SmallVectorImpl<MCParsedAsmOperand*> &Operands);\n";
|
||||||
OS << " bool mnemonicIsValid(StringRef Mnemonic);\n";
|
OS << " bool mnemonicIsValid(StringRef Mnemonic, unsigned VariantID);\n";
|
||||||
OS << " unsigned MatchInstructionImpl(\n";
|
OS << " unsigned MatchInstructionImpl(\n";
|
||||||
OS.indent(27);
|
OS.indent(27);
|
||||||
OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
|
OS << "const SmallVectorImpl<MCParsedAsmOperand*> &Operands,\n"
|
||||||
@ -2780,7 +2780,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
<< " RequiredFeatures;\n";
|
<< " RequiredFeatures;\n";
|
||||||
OS << " " << getMinimalTypeForRange(Info.Classes.size())
|
OS << " " << getMinimalTypeForRange(Info.Classes.size())
|
||||||
<< " Classes[" << MaxNumOperands << "];\n";
|
<< " Classes[" << MaxNumOperands << "];\n";
|
||||||
OS << " uint8_t AsmVariantID;\n\n";
|
|
||||||
OS << " StringRef getMnemonic() const {\n";
|
OS << " StringRef getMnemonic() const {\n";
|
||||||
OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n";
|
OS << " return StringRef(MnemonicTable + Mnemonic + 1,\n";
|
||||||
OS << " MnemonicTable[Mnemonic]);\n";
|
OS << " MnemonicTable[Mnemonic]);\n";
|
||||||
@ -2802,51 +2801,73 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
|
|
||||||
OS << "} // end anonymous namespace.\n\n";
|
OS << "} // end anonymous namespace.\n\n";
|
||||||
|
|
||||||
OS << "static const MatchEntry MatchTable["
|
unsigned VariantCount = Target.getAsmParserVariantCount();
|
||||||
<< Info.Matchables.size() << "] = {\n";
|
for (unsigned VC = 0; VC != VariantCount; ++VC) {
|
||||||
|
Record *AsmVariant = Target.getAsmParserVariant(VC);
|
||||||
|
std::string CommentDelimiter =
|
||||||
|
AsmVariant->getValueAsString("CommentDelimiter");
|
||||||
|
std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
|
||||||
|
int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
|
||||||
|
|
||||||
for (std::vector<MatchableInfo*>::const_iterator it =
|
OS << "static const MatchEntry MatchTable" << VC << "[] = {\n";
|
||||||
Info.Matchables.begin(), ie = Info.Matchables.end();
|
|
||||||
it != ie; ++it) {
|
|
||||||
MatchableInfo &II = **it;
|
|
||||||
|
|
||||||
// Store a pascal-style length byte in the mnemonic.
|
for (std::vector<MatchableInfo*>::const_iterator it =
|
||||||
std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
|
Info.Matchables.begin(), ie = Info.Matchables.end();
|
||||||
OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
|
it != ie; ++it) {
|
||||||
<< " /* " << II.Mnemonic << " */, "
|
MatchableInfo &II = **it;
|
||||||
<< Target.getName() << "::"
|
if (II.AsmVariantID != AsmVariantNo)
|
||||||
<< II.getResultInst()->TheDef->getName() << ", "
|
continue;
|
||||||
<< II.ConversionFnKind << ", ";
|
|
||||||
|
|
||||||
// Write the required features mask.
|
// Store a pascal-style length byte in the mnemonic.
|
||||||
if (!II.RequiredFeatures.empty()) {
|
std::string LenMnemonic = char(II.Mnemonic.size()) + II.Mnemonic.str();
|
||||||
for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
|
OS << " { " << StringTable.GetOrAddStringOffset(LenMnemonic, false)
|
||||||
if (i) OS << "|";
|
<< " /* " << II.Mnemonic << " */, "
|
||||||
OS << II.RequiredFeatures[i]->getEnumName();
|
<< Target.getName() << "::"
|
||||||
|
<< II.getResultInst()->TheDef->getName() << ", "
|
||||||
|
<< II.ConversionFnKind << ", ";
|
||||||
|
|
||||||
|
// Write the required features mask.
|
||||||
|
if (!II.RequiredFeatures.empty()) {
|
||||||
|
for (unsigned i = 0, e = II.RequiredFeatures.size(); i != e; ++i) {
|
||||||
|
if (i) OS << "|";
|
||||||
|
OS << II.RequiredFeatures[i]->getEnumName();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
OS << "0";
|
||||||
|
|
||||||
|
OS << ", { ";
|
||||||
|
for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
|
||||||
|
MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
|
||||||
|
|
||||||
|
if (i) OS << ", ";
|
||||||
|
OS << Op.Class->Name;
|
||||||
}
|
}
|
||||||
} else
|
OS << " }, },\n";
|
||||||
OS << "0";
|
|
||||||
|
|
||||||
OS << ", { ";
|
|
||||||
for (unsigned i = 0, e = II.AsmOperands.size(); i != e; ++i) {
|
|
||||||
MatchableInfo::AsmOperand &Op = II.AsmOperands[i];
|
|
||||||
|
|
||||||
if (i) OS << ", ";
|
|
||||||
OS << Op.Class->Name;
|
|
||||||
}
|
}
|
||||||
OS << " }, " << II.AsmVariantID;
|
|
||||||
OS << "},\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
OS << "};\n\n";
|
OS << "};\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
// A method to determine if a mnemonic is in the list.
|
// A method to determine if a mnemonic is in the list.
|
||||||
OS << "bool " << Target.getName() << ClassName << "::\n"
|
OS << "bool " << Target.getName() << ClassName << "::\n"
|
||||||
<< "mnemonicIsValid(StringRef Mnemonic) {\n";
|
<< "mnemonicIsValid(StringRef Mnemonic, unsigned VariantID) {\n";
|
||||||
|
OS << " // Find the appropriate table for this asm variant.\n";
|
||||||
|
OS << " const MatchEntry *Start, *End;\n";
|
||||||
|
OS << " switch (VariantID) {\n";
|
||||||
|
OS << " default: // unreachable\n";
|
||||||
|
for (unsigned VC = 0; VC != VariantCount; ++VC) {
|
||||||
|
Record *AsmVariant = Target.getAsmParserVariant(VC);
|
||||||
|
std::string CommentDelimiter =
|
||||||
|
AsmVariant->getValueAsString("CommentDelimiter");
|
||||||
|
std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
|
||||||
|
int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
|
||||||
|
OS << " case " << AsmVariantNo << ": Start = MatchTable" << VC
|
||||||
|
<< "; End = array_endof(MatchTable" << VC << "); break;\n";
|
||||||
|
}
|
||||||
|
OS << " }\n";
|
||||||
OS << " // Search the table.\n";
|
OS << " // Search the table.\n";
|
||||||
OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
|
OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
|
||||||
OS << " std::equal_range(MatchTable, MatchTable+"
|
OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n";
|
||||||
<< Info.Matchables.size() << ", Mnemonic, LessOpcode());\n";
|
|
||||||
OS << " return MnemonicRange.first != MnemonicRange.second;\n";
|
OS << " return MnemonicRange.first != MnemonicRange.second;\n";
|
||||||
OS << "}\n\n";
|
OS << "}\n\n";
|
||||||
|
|
||||||
@ -2888,10 +2909,23 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
OS << " ErrorInfo = ~0U;\n";
|
OS << " ErrorInfo = ~0U;\n";
|
||||||
|
|
||||||
// Emit code to search the table.
|
// Emit code to search the table.
|
||||||
|
OS << " // Find the appropriate table for this asm variant.\n";
|
||||||
|
OS << " const MatchEntry *Start, *End;\n";
|
||||||
|
OS << " switch (VariantID) {\n";
|
||||||
|
OS << " default: // unreachable\n";
|
||||||
|
for (unsigned VC = 0; VC != VariantCount; ++VC) {
|
||||||
|
Record *AsmVariant = Target.getAsmParserVariant(VC);
|
||||||
|
std::string CommentDelimiter =
|
||||||
|
AsmVariant->getValueAsString("CommentDelimiter");
|
||||||
|
std::string RegisterPrefix = AsmVariant->getValueAsString("RegisterPrefix");
|
||||||
|
int AsmVariantNo = AsmVariant->getValueAsInt("Variant");
|
||||||
|
OS << " case " << AsmVariantNo << ": Start = MatchTable" << VC
|
||||||
|
<< "; End = array_endof(MatchTable" << VC << "); break;\n";
|
||||||
|
}
|
||||||
|
OS << " }\n";
|
||||||
OS << " // Search the table.\n";
|
OS << " // Search the table.\n";
|
||||||
OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
|
OS << " std::pair<const MatchEntry*, const MatchEntry*> MnemonicRange =\n";
|
||||||
OS << " std::equal_range(MatchTable, MatchTable+"
|
OS << " std::equal_range(Start, End, Mnemonic, LessOpcode());\n\n";
|
||||||
<< Info.Matchables.size() << ", Mnemonic, LessOpcode());\n\n";
|
|
||||||
|
|
||||||
OS << " // Return a more specific error code if no mnemonics match.\n";
|
OS << " // Return a more specific error code if no mnemonics match.\n";
|
||||||
OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
|
OS << " if (MnemonicRange.first == MnemonicRange.second)\n";
|
||||||
@ -2905,7 +2939,6 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
|||||||
OS << " assert(Mnemonic == it->getMnemonic());\n";
|
OS << " assert(Mnemonic == it->getMnemonic());\n";
|
||||||
|
|
||||||
// Emit check that the subclasses match.
|
// Emit check that the subclasses match.
|
||||||
OS << " if (VariantID != it->AsmVariantID) continue;\n";
|
|
||||||
OS << " bool OperandsValid = true;\n";
|
OS << " bool OperandsValid = true;\n";
|
||||||
OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n";
|
OS << " for (unsigned i = 0; i != " << MaxNumOperands << "; ++i) {\n";
|
||||||
OS << " if (i + 1 >= Operands.size()) {\n";
|
OS << " if (i + 1 >= Operands.size()) {\n";
|
||||||
|
Reference in New Issue
Block a user