diff --git a/llvm/include/llvm/MC/MCInstPrinter.h b/llvm/include/llvm/MC/MCInstPrinter.h --- a/llvm/include/llvm/MC/MCInstPrinter.h +++ b/llvm/include/llvm/MC/MCInstPrinter.h @@ -88,6 +88,10 @@ /// Specify a stream to emit comments to. void setCommentStream(raw_ostream &OS) { CommentStream = &OS; } + /// Returns a pair containing the mnemonic for \p MI and the number of bits + /// left for further processing by printInstruction (generated by tablegen). + virtual std::pair getMnemonic(const MCInst *MI) = 0; + /// Print the specified MCInst to the specified raw_ostream. /// /// \p Address the address of current instruction on most targets, used to diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -30,6 +30,7 @@ void printRegName(raw_ostream &OS, unsigned RegNo) const override; // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; virtual void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O); virtual bool printAliasInstr(const MCInst *MI, uint64_t Address, @@ -203,6 +204,7 @@ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override; + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O) override; bool printAliasInstr(const MCInst *MI, uint64_t Address, diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h @@ -24,6 +24,7 @@ //Autogenerated by tblgen void printRegName(raw_ostream &OS, unsigned RegNo) const override; + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); @@ -253,6 +254,7 @@ void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override; + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h --- a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h +++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h @@ -26,6 +26,7 @@ : MCInstPrinter(MAI, MII, MRI) {} // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h @@ -30,6 +30,7 @@ void printRegName(raw_ostream &OS, unsigned RegNo) const override; // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O); virtual bool printAliasInstr(const MCInst *MI, uint64_t Address, diff --git a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h @@ -45,6 +45,7 @@ void printMemri(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by TableGen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &O); void printCustomAliasOperand(const MCInst *MI, uint64_t Address, diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h b/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h @@ -32,6 +32,7 @@ void printBrTargetOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); }; diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h @@ -34,6 +34,7 @@ static char const *getRegisterName(unsigned RegNo); + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); void printOperand(MCInst const *MI, unsigned OpNo, raw_ostream &O) const; void printBrtarget(MCInst const *MI, unsigned OpNo, raw_ostream &O) const; diff --git a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.h b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.h --- a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.h +++ b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.h @@ -43,6 +43,7 @@ void printMemImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O); // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &OS); void printCustomAliasOperand(const MCInst *MI, uint64_t Address, diff --git a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h --- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h @@ -26,6 +26,7 @@ const MCSubtargetInfo &STI, raw_ostream &O) override; // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); bool printAliasInstr(const MCInst *MI, uint64_t Address, raw_ostream &O); void printCustomAliasOperand(const MCInst *MI, uint64_t Address, diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h @@ -79,6 +79,7 @@ : MCInstPrinter(MAI, MII, MRI) {} // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h --- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h +++ b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h @@ -29,6 +29,7 @@ const MCSubtargetInfo &STI, raw_ostream &OS) override; // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); // End diff --git a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h @@ -36,6 +36,7 @@ const MCSubtargetInfo &STI, raw_ostream &O) override; // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -48,6 +48,7 @@ const MCSubtargetInfo &STI, raw_ostream &O); // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O); bool printAliasInstr(const MCInst *MI, uint64_t Address, diff --git a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h @@ -31,6 +31,7 @@ bool isV9(const MCSubtargetInfo &STI) const; // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, const MCSubtargetInfo &STI, raw_ostream &O); bool printAliasInstr(const MCInst *MI, uint64_t Address, diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h @@ -27,6 +27,7 @@ : MCInstPrinter(MAI, MII, MRI) {} // Automatically generated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h @@ -50,6 +50,7 @@ raw_ostream &O); // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); }; diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h --- a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h @@ -36,6 +36,7 @@ raw_ostream &O); // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &OS); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h b/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h --- a/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h @@ -37,6 +37,7 @@ raw_ostream &O); // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/lib/Target/XCore/MCTargetDesc/XCoreInstPrinter.h b/llvm/lib/Target/XCore/MCTargetDesc/XCoreInstPrinter.h --- a/llvm/lib/Target/XCore/MCTargetDesc/XCoreInstPrinter.h +++ b/llvm/lib/Target/XCore/MCTargetDesc/XCoreInstPrinter.h @@ -27,6 +27,7 @@ : MCInstPrinter(MAI, MII, MRI) {} // Autogenerated by tblgen. + std::pair getMnemonic(const MCInst *MI) override; void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O); static const char *getRegisterName(unsigned RegNo); diff --git a/llvm/utils/TableGen/AsmWriterEmitter.cpp b/llvm/utils/TableGen/AsmWriterEmitter.cpp --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -64,9 +64,15 @@ AsmWriterEmitter(RecordKeeper &R); void run(raw_ostream &o); - private: - void EmitPrintInstruction(raw_ostream &o); + void EmitGetMnemonic( + raw_ostream &o, + std::vector> &TableDrivenOperandPrinters, + unsigned &BitsLeft, unsigned &AsmStrBits); + void EmitPrintInstruction( + raw_ostream &o, + std::vector> &TableDrivenOperandPrinters, + unsigned &BitsLeft, unsigned &AsmStrBits); void EmitGetRegisterName(raw_ostream &o); void EmitPrintAliasInstruction(raw_ostream &O); @@ -288,22 +294,19 @@ } } -/// 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> &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 " + << Target.getName() << ClassName << "::getMnemonic(const MCInst *MI) {\n"; // Build an aggregate string, and build a table of offsets into it. SequenceToOffsetTable StringTable; @@ -349,13 +352,11 @@ } // 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> TableDrivenOperandPrinters; + BitsLeft = OpcodeInfoBits - AsmStrBits; while (true) { std::vector UniqueOperandCommands; @@ -435,16 +436,45 @@ ++Table; } - // Emit the initial tab character. - O << " O << \"\\t\";\n\n"; - O << " // Emit the opcode for the instruction.\n"; O << BitsString; // Emit the starting string. - O << " assert(Bits != 0 && \"Cannot print this instruction.\");\n" - << " O << AsmStrs+(Bits & " << (1 << AsmStrBits)-1 << ")-1;\n\n"; + 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> &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"; + + 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; for (unsigned i = 0, e = TableDrivenOperandPrinters.size(); i != e; ++i) { @@ -1262,7 +1292,11 @@ } void AsmWriterEmitter::run(raw_ostream &O) { - EmitPrintInstruction(O); + std::vector> TableDrivenOperandPrinters; + unsigned BitsLeft = 0; + unsigned AsmStrBits = 0; + EmitGetMnemonic(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits); + EmitPrintInstruction(O, TableDrivenOperandPrinters, BitsLeft, AsmStrBits); EmitGetRegisterName(O); EmitPrintAliasInstruction(O); }