diff options
Diffstat (limited to 'llvm/utils/TableGen/AsmWriterEmitter.cpp')
| -rw-r--r-- | llvm/utils/TableGen/AsmWriterEmitter.cpp | 113 |
1 files changed, 71 insertions, 42 deletions
diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp index d10ea71e97e3..92df204475b9 100644 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -64,9 +64,15 @@ public: AsmWriterEmitter(RecordKeeper &R); void run(raw_ostream &o); - private: - void EmitPrintInstruction(raw_ostream &o); + void EmitGetMnemonic( + raw_ostream &o, + std::vector<std::vector<std::string>> &TableDrivenOperandPrinters, + unsigned &BitsLeft, unsigned &AsmStrBits); + void EmitPrintInstruction( + raw_ostream &o, + std::vector<std::vector<std::string>> &TableDrivenOperandPrinters, + unsigned &BitsLeft, unsigned &AsmStrBits); void EmitGetRegisterName(raw_ostream &o); void EmitPrintAliasInstruction(raw_ostream &O); @@ -212,12 +218,11 @@ FindUniqueOperandCommands(std::vector<std::string> &UniqueOperandCommands, // Otherwise, scan to see if all of the other instructions in this command // set share the operand. - if (std::any_of(Idxs.begin()+1, Idxs.end(), - [&](unsigned Idx) { - const AsmWriterInst &OtherInst = Instructions[Idx]; - return OtherInst.Operands.size() == Op || - OtherInst.Operands[Op] != FirstInst.Operands[Op]; - })) + if (any_of(drop_begin(Idxs), [&](unsigned Idx) { + const AsmWriterInst &OtherInst = Instructions[Idx]; + return OtherInst.Operands.size() == Op || + OtherInst.Operands[Op] != FirstInst.Operands[Op]; + })) break; // Okay, everything in this command set has the same next operand. Add it @@ -288,22 +293,19 @@ static void UnescapeAliasString(std::string &Str) { } } -/// EmitPrintInstruction - Generate the code for the "printInstruction" method -/// implementation. Destroys all instances of AsmWriterInst information, by -/// clearing the Instructions vector. -void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { +void AsmWriterEmitter::EmitGetMnemonic( + raw_ostream &O, + std::vector<std::vector<std::string>> &TableDrivenOperandPrinters, + unsigned &BitsLeft, unsigned &AsmStrBits) { Record *AsmWriter = Target.getAsmWriter(); StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); - O << "/// printInstruction - This method is automatically generated by " + O << "/// getMnemonic - This method is automatically generated by " "tablegen\n" "/// from the instruction set description.\n" - "void " - << Target.getName() << ClassName - << "::printInstruction(const MCInst *MI, uint64_t Address, " - << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") - << "raw_ostream &O) {\n"; + "std::pair<const char *, uint64_t> " + << Target.getName() << ClassName << "::getMnemonic(const MCInst *MI) {\n"; // Build an aggregate string, and build a table of offsets into it. SequenceToOffsetTable<std::string> StringTable; @@ -349,13 +351,11 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { } // Figure out how many bits we used for the string index. - unsigned AsmStrBits = Log2_32_Ceil(MaxStringIdx+2); + AsmStrBits = Log2_32_Ceil(MaxStringIdx + 2); // To reduce code size, we compactify common instructions into a few bits // in the opcode-indexed table. - unsigned BitsLeft = OpcodeInfoBits-AsmStrBits; - - std::vector<std::vector<std::string>> TableDrivenOperandPrinters; + BitsLeft = OpcodeInfoBits - AsmStrBits; while (true) { std::vector<std::string> UniqueOperandCommands; @@ -435,15 +435,47 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { ++Table; } - // Emit the initial tab character. - O << " O << \"\\t\";\n\n"; - O << " // Emit the opcode for the instruction.\n"; O << BitsString; + // Return mnemonic string and bits. + O << " return {AsmStrs+(Bits & " << (1 << AsmStrBits) - 1 + << ")-1, Bits};\n\n"; + + O << "}\n"; +} + +/// EmitPrintInstruction - Generate the code for the "printInstruction" method +/// implementation. Destroys all instances of AsmWriterInst information, by +/// clearing the Instructions vector. +void AsmWriterEmitter::EmitPrintInstruction( + raw_ostream &O, + std::vector<std::vector<std::string>> &TableDrivenOperandPrinters, + unsigned &BitsLeft, unsigned &AsmStrBits) { + const unsigned OpcodeInfoBits = 64; + Record *AsmWriter = Target.getAsmWriter(); + StringRef ClassName = AsmWriter->getValueAsString("AsmWriterClassName"); + bool PassSubtarget = AsmWriter->getValueAsInt("PassSubtarget"); + + O << "/// printInstruction - This method is automatically generated by " + "tablegen\n" + "/// from the instruction set description.\n" + "void " + << Target.getName() << ClassName + << "::printInstruction(const MCInst *MI, uint64_t Address, " + << (PassSubtarget ? "const MCSubtargetInfo &STI, " : "") + << "raw_ostream &O) {\n"; + + // Emit the initial tab character. + O << " O << \"\\t\";\n\n"; + // Emit the starting string. - O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" - << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; + O << " auto MnemonicInfo = getMnemonic(MI);\n\n"; + O << " O << MnemonicInfo.first;\n\n"; + + O << " uint" << ((BitsLeft < (OpcodeInfoBits - 32)) ? 64 : 32) + << "_t Bits = MnemonicInfo.second;\n" + << " assert(Bits != 0 && \"Cannot print this instruction.\");\n"; // Output the table driven operand information. BitsLeft = OpcodeInfoBits-AsmStrBits; @@ -489,10 +521,8 @@ void AsmWriterEmitter::EmitPrintInstruction(raw_ostream &O) { } // Okay, delete instructions with no operand info left. - auto I = llvm::remove_if(Instructions, - [](AsmWriterInst &Inst) { return Inst.Operands.empty(); }); - Instructions.erase(I, Instructions.end()); - + llvm::erase_if(Instructions, + [](AsmWriterInst &Inst) { return Inst.Operands.empty(); }); // Because this is a vector, we want to emit from the end. Reverse all of the // elements in the vector. @@ -683,9 +713,7 @@ public: ++Next; } else { // $name, just eat the usual suspects. - while (I != End && - ((*I >= 'a' && *I <= 'z') || (*I >= 'A' && *I <= 'Z') || - (*I >= '0' && *I <= '9') || *I == '_')) + while (I != End && (isAlnum(*I) || *I == '_')) ++I; Next = I; } @@ -1232,13 +1260,10 @@ void AsmWriterEmitter::EmitPrintAliasInstruction(raw_ostream &O) { << " break;\n"; for (unsigned i = 0; i < MCOpPredicates.size(); ++i) { - Init *MCOpPred = MCOpPredicates[i]->getValueInit("MCOperandPredicate"); - if (CodeInit *SI = dyn_cast<CodeInit>(MCOpPred)) { - O << " case " << i + 1 << ": {\n" - << SI->getValue() << "\n" - << " }\n"; - } else - llvm_unreachable("Unexpected MCOperandPredicate field!"); + StringRef MCOpPred = MCOpPredicates[i]->getValueAsString("MCOperandPredicate"); + O << " case " << i + 1 << ": {\n" + << MCOpPred.data() << "\n" + << " }\n"; } O << " }\n" << "}\n\n"; @@ -1262,7 +1287,11 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) { } void AsmWriterEmitter::run(raw_ostream &O) { - EmitPrintInstruction(O); + std::vector<std::vector<std::string>> TableDrivenOperandPrinters; + unsigned BitsLeft = 0; + unsigned AsmStrBits = 0; + EmitGetMnemonic(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits); + EmitPrintInstruction(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits); EmitGetRegisterName(O); EmitPrintAliasInstruction(O); } |
