diff --git a/llvm/include/llvm/MC/MCInstPrinter.h b/llvm/include/llvm/MC/MCInstPrinter.h index 751c2bdbf80b3c..8b9ef178e33c1b 100644 --- a/llvm/include/llvm/MC/MCInstPrinter.h +++ b/llvm/include/llvm/MC/MCInstPrinter.h @@ -88,6 +88,10 @@ class MCInstPrinter { /// 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 index 6da5f0e81c803e..20c4e4c750ec6b 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -30,6 +30,7 @@ class AArch64InstPrinter : public MCInstPrinter { 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 @@ class AArch64AppleInstPrinter : public AArch64InstPrinter { 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 index ed45c5309ea256..64ccb9092ec49a 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.h @@ -24,6 +24,7 @@ class AMDGPUInstPrinter : public MCInstPrinter { //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 @@ class R600InstPrinter : public MCInstPrinter { 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 index 266f2de087727d..bcb790c2fa5762 100644 --- a/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h +++ b/llvm/lib/Target/ARC/MCTargetDesc/ARCInstPrinter.h @@ -26,6 +26,7 @@ class ARCInstPrinter : public MCInstPrinter { : 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 index 37cb731ff0014d..d975d799e07916 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMInstPrinter.h @@ -30,6 +30,7 @@ class ARMInstPrinter : public MCInstPrinter { 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 index 910fd3455dee33..8976ef28f3dcac 100644 --- a/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h +++ b/llvm/lib/Target/AVR/MCTargetDesc/AVRInstPrinter.h @@ -45,6 +45,7 @@ class AVRInstPrinter : public MCInstPrinter { 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 index 2181bb575cdda0..e76067ea41aed2 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFInstPrinter.h @@ -32,6 +32,7 @@ class BPFInstPrinter : public MCInstPrinter { 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 index cd96a23e1b94c6..76658378c0cd6d 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonInstPrinter.h @@ -34,6 +34,7 @@ class HexagonInstPrinter : public MCInstPrinter { 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 index ce6df2969d734e..f0d287c858d864 100644 --- a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.h +++ b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiInstPrinter.h @@ -43,6 +43,7 @@ class LanaiInstPrinter : public MCInstPrinter { 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 index 6a6b07f2eba01e..08c466377ee3d3 100644 --- a/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h +++ b/llvm/lib/Target/MSP430/MCTargetDesc/MSP430InstPrinter.h @@ -26,6 +26,7 @@ namespace llvm { 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 index 3f534a2f184354..68b13bf1fcc35c 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsInstPrinter.h @@ -79,6 +79,7 @@ class MipsInstPrinter : public MCInstPrinter { : 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 index cee0e7eec54afa..503f0497b6f05c 100644 --- a/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h +++ b/llvm/lib/Target/NVPTX/MCTargetDesc/NVPTXInstPrinter.h @@ -29,6 +29,7 @@ class NVPTXInstPrinter : public MCInstPrinter { 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 index 9763aeceef941b..2b5414458ce6b4 100644 --- a/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h +++ b/llvm/lib/Target/PowerPC/MCTargetDesc/PPCInstPrinter.h @@ -36,6 +36,7 @@ class PPCInstPrinter : public MCInstPrinter { 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 index fdaa00c5f8ebc0..70ec0fe2a0cc71 100644 --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVInstPrinter.h @@ -48,6 +48,7 @@ class RISCVInstPrinter : public MCInstPrinter { 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 index 11587f165ef297..91b78bd03fc389 100644 --- a/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h +++ b/llvm/lib/Target/Sparc/MCTargetDesc/SparcInstPrinter.h @@ -31,6 +31,7 @@ class SparcInstPrinter : public MCInstPrinter { 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 index cfe1bd89c3eb2a..0db7279a06c13c 100644 --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h @@ -27,6 +27,7 @@ class SystemZInstPrinter : public MCInstPrinter { : 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 index f40cef233ac51b..c46411b10b09e2 100644 --- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h +++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.h @@ -52,6 +52,7 @@ class WebAssemblyInstPrinter final : public MCInstPrinter { 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 index 51ddae61d25102..f7a850571260a3 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86ATTInstPrinter.h @@ -36,6 +36,7 @@ class X86ATTInstPrinter final : public X86InstPrinterCommon { 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 index 82baf611df0383..aa4d0545ea4686 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86IntelInstPrinter.h @@ -37,6 +37,7 @@ class X86IntelInstPrinter final : public X86InstPrinterCommon { 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 index c7868bf4cf8e04..0ea47106434c9e 100644 --- a/llvm/lib/Target/XCore/MCTargetDesc/XCoreInstPrinter.h +++ b/llvm/lib/Target/XCore/MCTargetDesc/XCoreInstPrinter.h @@ -27,6 +27,7 @@ class XCoreInstPrinter : public MCInstPrinter { : 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 index dfbe8716411d6f..f903be16947604 100644 --- a/llvm/utils/TableGen/AsmWriterEmitter.cpp +++ b/llvm/utils/TableGen/AsmWriterEmitter.cpp @@ -64,9 +64,15 @@ class AsmWriterEmitter { 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 @@ 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> &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 @@ 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> TableDrivenOperandPrinters; + BitsLeft = OpcodeInfoBits - AsmStrBits; while (true) { std::vector UniqueOperandCommands; @@ -435,15 +436,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> &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; @@ -1262,7 +1295,11 @@ AsmWriterEmitter::AsmWriterEmitter(RecordKeeper &R) : Records(R), Target(R) { } 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); }