diff options
Diffstat (limited to 'contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp')
-rw-r--r-- | contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp | 138 |
1 files changed, 71 insertions, 67 deletions
diff --git a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp index ac8d896..a18b6b5 100644 --- a/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/contrib/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" @@ -31,10 +32,12 @@ using namespace llvm; namespace { class AsmWriterEmitter { RecordKeeper &Records; + CodeGenTarget Target; std::map<const CodeGenInstruction*, AsmWriterInst*> CGIAWIMap; std::vector<const CodeGenInstruction*> NumberedInstructions; + std::vector<AsmWriterInst> Instructions; public: - AsmWriterEmitter(RecordKeeper &R) : Records(R) {} + AsmWriterEmitter(RecordKeeper &R); void run(raw_ostream &o); @@ -272,9 +275,9 @@ static void UnescapeString(std::string &Str) { } /// EmitPrintInstruction - Generate the code for the "printInstruction" method -/// implementation. +/// implementation. Destroys all instances of AsmWriterInst information, by +/// clearing the Instructions vector. void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { - CodeGenTarget Target(Records); Record *AsmWriter = Target.getAsmWriter(); std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); bool isMC = AsmWriter->getValueAsBit("isMCAsmWriter"); @@ -287,27 +290,6 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { << "::printInstruction(const " << MachineInstrClassName << " *MI, raw_ostream &O) {\n"; - std::vector<AsmWriterInst> Instructions; - - for (CodeGenTarget::inst_iterator I = Target.inst_begin(), - E = Target.inst_end(); I != E; ++I) - if (!(*I)->AsmString.empty() && - (*I)->TheDef->getName() != "PHI") - Instructions.push_back( - AsmWriterInst(**I, - AsmWriter->getValueAsInt("Variant"), - AsmWriter->getValueAsInt("FirstOperandColumn"), - AsmWriter->getValueAsInt("OperandSpacing"))); - - // Get the instruction numbering. - NumberedInstructions = Target.getInstructionsByEnumValue(); - - // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not - // all machine instructions are necessarily being printed, so there may be - // target instructions not in this map. - for (unsigned i = 0, e = Instructions.size(); i != e; ++i) - CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); - // Build an aggregate string, and build a table of offsets into it. SequenceToOffsetTable<std::string> StringTable; @@ -591,7 +573,6 @@ emitRegisterNameString(raw_ostream &O, StringRef AltName, } void AsmWriterEmitter::EmitGetRegisterName(raw_ostream &O) { - CodeGenTarget Target(Records); Record *AsmWriter = Target.getAsmWriter(); std::string ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); const std::vector<CodeGenRegister*> &Registers = @@ -657,7 +638,10 @@ public: void addCond(const std::string &C) { Conds.push_back(C); } - void addOperand(StringRef Op, unsigned Idx) { OpMap[Op] = Idx; } + void addOperand(StringRef Op, unsigned Idx) { + assert(Idx < 0xFF && "Index too large!"); + OpMap[Op] = Idx; + } unsigned getOpIndex(StringRef Op) { return OpMap[Op]; } bool isOpMapped(StringRef Op) { return OpMap.find(Op) != OpMap.end(); } @@ -681,12 +665,35 @@ public: O << ") {\n"; O.indent(6) << "// " << Result << "\n"; - O.indent(6) << "AsmString = \"" << AsmString << "\";\n"; - for (std::map<StringRef, unsigned>::iterator - I = OpMap.begin(), E = OpMap.end(); I != E; ++I) - O.indent(6) << "OpMap.push_back(std::make_pair(\"" << I->first << "\", " - << I->second << "));\n"; + // Directly mangle mapped operands into the string. Each operand is + // identified by a '$' sign followed by a byte identifying the number of the + // operand. We add one to the index to avoid zero bytes. + std::pair<StringRef, StringRef> ASM = StringRef(AsmString).split(' '); + SmallString<128> OutString = ASM.first; + if (!ASM.second.empty()) { + raw_svector_ostream OS(OutString); + OS << ' '; + for (StringRef::iterator I = ASM.second.begin(), E = ASM.second.end(); + I != E;) { + OS << *I; + if (*I == '$') { + StringRef::iterator Start = ++I; + while (I != E && + ((*I >= 'a' && *I <= 'z') || (*I >= 'A' && *I <= 'Z') || + (*I >= '0' && *I <= '9') || *I == '_')) + ++I; + StringRef Name(Start, I - Start); + assert(isOpMapped(Name) && "Unmapped operand!"); + OS << format("\\x%02X", (unsigned char)getOpIndex(Name) + 1); + } else { + ++I; + } + } + } + + // Emit the string. + O.indent(6) << "AsmString = \"" << OutString.str() << "\";\n"; O.indent(6) << "break;\n"; O.indent(4) << '}'; @@ -721,19 +728,6 @@ public: } // end anonymous namespace -static void EmitGetMapOperandNumber(raw_ostream &O) { - O << "static unsigned getMapOperandNumber(" - << "const SmallVectorImpl<std::pair<StringRef, unsigned> > &OpMap,\n"; - O << " StringRef Name) {\n"; - O << " for (SmallVectorImpl<std::pair<StringRef, unsigned> >::" - << "const_iterator\n"; - O << " I = OpMap.begin(), E = OpMap.end(); I != E; ++I)\n"; - O << " if (I->first == Name)\n"; - O << " return I->second;\n"; - O << " llvm_unreachable(\"Operand not in map!\");\n"; - O << "}\n\n"; -} - static unsigned CountNumOperands(StringRef AsmString) { unsigned NumOps = 0; std::pair<StringRef, StringRef> ASM = AsmString.split(' '); @@ -768,7 +762,6 @@ static unsigned CountResultNumOperands(StringRef AsmString) { } void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { - CodeGenTarget Target(Records); Record *AsmWriter = Target.getAsmWriter(); if (!AsmWriter->getValueAsBit("isMCAsmWriter")) @@ -822,7 +815,6 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { Cond = std::string("MI->getNumOperands() == ") + llvm::utostr(LastOpNo); IAP->addCond(Cond); - std::map<StringRef, unsigned> OpMap; bool CantHandle = false; for (unsigned i = 0, e = LastOpNo; i != e; ++i) { @@ -955,11 +947,8 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { return; } - EmitGetMapOperandNumber(O); - O << HeaderO.str(); - O.indent(2) << "StringRef AsmString;\n"; - O.indent(2) << "SmallVector<std::pair<StringRef, unsigned>, 4> OpMap;\n"; + O.indent(2) << "const char *AsmString;\n"; O.indent(2) << "switch (MI->getOpcode()) {\n"; O.indent(2) << "default: return false;\n"; O << CasesO.str(); @@ -967,27 +956,21 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { // Code that prints the alias, replacing the operands with the ones from the // MCInst. - O << " std::pair<StringRef, StringRef> ASM = AsmString.split(' ');\n"; - O << " OS << '\\t' << ASM.first;\n"; + O << " unsigned I = 0;\n"; + O << " while (AsmString[I] != ' ' && AsmString[I] != '\\0')\n"; + O << " ++I;\n"; + O << " OS << '\\t' << StringRef(AsmString, I);\n"; - O << " if (!ASM.second.empty()) {\n"; + O << " if (AsmString[I] != '\\0') {\n"; O << " OS << '\\t';\n"; - O << " for (StringRef::iterator\n"; - O << " I = ASM.second.begin(), E = ASM.second.end(); I != E; ) {\n"; - O << " if (*I == '$') {\n"; - O << " StringRef::iterator Start = ++I;\n"; - O << " while (I != E &&\n"; - O << " ((*I >= 'a' && *I <= 'z') ||\n"; - O << " (*I >= 'A' && *I <= 'Z') ||\n"; - O << " (*I >= '0' && *I <= '9') ||\n"; - O << " *I == '_'))\n"; - O << " ++I;\n"; - O << " StringRef Name(Start, I - Start);\n"; - O << " printOperand(MI, getMapOperandNumber(OpMap, Name), OS);\n"; + O << " do {\n"; + O << " if (AsmString[I] == '$') {\n"; + O << " ++I;\n"; + O << " printOperand(MI, unsigned(AsmString[I++]) - 1, OS);\n"; O << " } else {\n"; - O << " OS << *I++;\n"; + O << " OS << AsmString[I++];\n"; O << " }\n"; - O << " }\n"; + O << " } while (AsmString[I] != '\\0');\n"; O << " }\n\n"; O << " return true;\n"; @@ -996,6 +979,27 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { O << "#endif // PRINT_ALIAS_INSTR\n"; } +AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) { + Record *AsmWriter = Target.getAsmWriter(); + for (CodeGenTarget::inst_iterator I = Target.inst_begin(), + E = Target.inst_end(); + I != E; ++I) + if (!(*I)->AsmString.empty() && (*I)->TheDef->getName() != "PHI") + Instructions.push_back( + AsmWriterInst(**I, AsmWriter->getValueAsInt("Variant"), + AsmWriter->getValueAsInt("FirstOperandColumn"), + AsmWriter->getValueAsInt("OperandSpacing"))); + + // Get the instruction numbering. + NumberedInstructions = Target.getInstructionsByEnumValue(); + + // Compute the CodeGenInstruction -> AsmWriterInst mapping. Note that not + // all machine instructions are necessarily being printed, so there may be + // target instructions not in this map. + for (unsigned i = 0, e = Instructions.size(); i != e; ++i) + CGIAWIMap.insert(std::make_pair(Instructions[i].CGI, &Instructions[i])); +} + void AsmWriterEmitter::run(raw_ostream &O) { EmitPrintInstruction(O); EmitGetRegisterName(O); |