From 175580c0f36b026daf9de0adabdb7ddcf7619db6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 14 Aug 2004 22:50:53 +0000 Subject: [PATCH] Make the AsmWriter a first-class tblgen object. Allow targets to specify name of the generated asmwriter class, and the name of the format string. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15747 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/Target.td | 53 +++++++++++++++++++++-------- utils/TableGen/AsmWriterEmitter.cpp | 11 ++++-- utils/TableGen/CodeGenInstruction.h | 2 +- utils/TableGen/CodeGenTarget.cpp | 21 +++++++++--- utils/TableGen/CodeGenTarget.h | 6 +++- 5 files changed, 70 insertions(+), 23 deletions(-) diff --git a/lib/Target/Target.td b/lib/Target/Target.td index 7158d4b0ba4..ac2c0281ea4 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -133,20 +133,6 @@ class Instruction { } -// InstrInfo - This class should only be instantiated once to provide parameters -// which are global to the the target machine. -// -class InstrInfo { - Instruction PHIInst; - - // If the target wants to associate some target-specific information with each - // instruction, it should provide these two lists to indicate how to assemble - // the target specific information into the 32 bits available. - // - list TSFlagsFields = []; - list TSFlagsShifts = []; -} - /// ops definition - This is just a simple marker used to identify the operands /// list for an instruction. This should be used like this: /// (ops R32:$dst, R32:$src) or something similar. @@ -166,6 +152,40 @@ def i16imm : Operand; def i32imm : Operand; def i64imm : Operand; +// InstrInfo - This class should only be instantiated once to provide parameters +// which are global to the the target machine. +// +class InstrInfo { + Instruction PHIInst; + + // If the target wants to associate some target-specific information with each + // instruction, it should provide these two lists to indicate how to assemble + // the target specific information into the 32 bits available. + // + list TSFlagsFields = []; + list TSFlagsShifts = []; +} + +//===----------------------------------------------------------------------===// +// AsmWriter - This class can be implemented by targets that need to customize +// the format of the .s file writer. +// +// Subtargets can have multiple different asmwriters (e.g. AT&T vs Intel syntax +// on X86 for example). +// +class AsmWriter { + // AsmWriterClassName - This specifies the suffix to use for the asmwriter + // class. Generated AsmWriter classes are always prefixed with the target + // name. + string AsmWriterClassName = "AsmPrinter"; + + // InstFormatName - AsmWriters can specify the name of the format string to + // print instructions with. + string InstFormatName = "AsmString"; +} +def DefaultAsmWriter : AsmWriter; + + //===----------------------------------------------------------------------===// // Target - This class contains the "global" target information // @@ -178,8 +198,11 @@ class Target { // this target. Typically this is an i32 or i64 type. ValueType PointerType; - // InstructionSet - Instruction set description for this target + // InstructionSet - Instruction set description for this target. InstrInfo InstructionSet; + + // AssemblyWriter - The AsmWriter instance to use for this target. + AsmWriter AssemblyWriter = DefaultAsmWriter; } diff --git a/utils/TableGen/AsmWriterEmitter.cpp b/utils/TableGen/AsmWriterEmitter.cpp index b2e2125f82a..7b3a5046c3c 100644 --- a/utils/TableGen/AsmWriterEmitter.cpp +++ b/utils/TableGen/AsmWriterEmitter.cpp @@ -14,6 +14,7 @@ #include "AsmWriterEmitter.h" #include "CodeGenTarget.h" +#include "Record.h" #include using namespace llvm; @@ -28,13 +29,19 @@ void AsmWriterEmitter::run(std::ostream &O) { EmitSourceFileHeader("Assembly Writer Source Fragment", O); CodeGenTarget Target; + + Record *AsmWriter = Target.getAsmWriter(); + + std::string AsmWriterClassName = + AsmWriter->getValueAsString("AsmWriterClassName"); + O << "/// printInstruction - This method is automatically generated by tablegen\n" "/// from the instruction set description. This method returns true if the\n" "/// machine instruction was sufficiently described to print it, otherwise\n" "/// it returns false.\n" - "bool " << Target.getName() - << "AsmPrinter::printInstruction(const MachineInstr *MI) {\n"; + "bool " << Target.getName() << AsmWriterClassName + << "::printInstruction(const MachineInstr *MI) {\n"; O << " switch (MI->getOpcode()) {\n" " default: return false;\n"; diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 85be70e650f..5e6af316356 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -74,7 +74,7 @@ namespace llvm { bool isTwoAddress; bool isTerminator; - CodeGenInstruction(Record *R); + CodeGenInstruction(Record *R, const std::string &AsmStr); /// getOperandNamed - Return the index of the operand with the specified /// non-empty name. If the instruction does not have an operand with the diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index e7ca8570280..9e52cbc39a2 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -97,14 +97,27 @@ Record *CodeGenTarget::getInstructionSet() const { return TargetRec->getValueAsDef("InstructionSet"); } +/// getAsmWriter - Return the AssemblyWriter definition for this target. +/// +Record *CodeGenTarget::getAsmWriter() const { + return TargetRec->getValueAsDef("AssemblyWriter"); +} + + void CodeGenTarget::ReadInstructions() const { std::vector Insts = Records.getAllDerivedDefinitions("Instruction"); if (Insts.size() == 0) throw std::string("No 'Instruction' subclasses defined!"); - for (unsigned i = 0, e = Insts.size(); i != e; ++i) - Instructions.insert(std::make_pair(Insts[i]->getName(), Insts[i])); + std::string InstFormatName = + getAsmWriter()->getValueAsString("InstFormatName"); + + for (unsigned i = 0, e = Insts.size(); i != e; ++i) { + std::string AsmStr = Insts[i]->getValueAsString(InstFormatName); + Instructions.insert(std::make_pair(Insts[i]->getName(), + CodeGenInstruction(Insts[i], AsmStr))); + } } /// getPHIInstruction - Return the designated PHI instruction. @@ -117,10 +130,10 @@ const CodeGenInstruction &CodeGenTarget::getPHIInstruction() const { return I->second; } -CodeGenInstruction::CodeGenInstruction(Record *R) : TheDef(R) { +CodeGenInstruction::CodeGenInstruction(Record *R, const std::string &AsmStr) + : TheDef(R), AsmString(AsmStr) { Name = R->getValueAsString("Name"); Namespace = R->getValueAsString("Namespace"); - AsmString = R->getValueAsString("AsmString"); isReturn = R->getValueAsBit("isReturn"); isBranch = R->getValueAsBit("isBranch"); diff --git a/utils/TableGen/CodeGenTarget.h b/utils/TableGen/CodeGenTarget.h index e711b8190c5..218fef82146 100644 --- a/utils/TableGen/CodeGenTarget.h +++ b/utils/TableGen/CodeGenTarget.h @@ -56,10 +56,14 @@ public: MVT::ValueType getPointerType() const { return PointerType; } - // getInstructionSet - Return the InstructionSet object. + /// getInstructionSet - Return the InstructionSet object. /// Record *getInstructionSet() const; + /// getAsmWriter - Return the AssemblyWriter definition for this target. + /// + Record *getAsmWriter() const; + /// getPHIInstruction - Return the designated PHI instruction. const CodeGenInstruction &getPHIInstruction() const;