Make the AsmWriter a first-class tblgen object. Allow targets to specify
authorChris Lattner <sabre@nondot.org>
Sat, 14 Aug 2004 22:50:53 +0000 (22:50 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 14 Aug 2004 22:50:53 +0000 (22:50 +0000)
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
utils/TableGen/AsmWriterEmitter.cpp
utils/TableGen/CodeGenInstruction.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/CodeGenTarget.h

index 7158d4b0ba4fffc88ed39ab18d2ae01043829b7d..ac2c0281ea4784fcd27af437e860b5aca69cc64d 100644 (file)
@@ -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<string> TSFlagsFields = [];
-  list<int>    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<i16>;
 def i32imm : Operand<i32>;
 def i64imm : Operand<i64>;
 
+// 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<string> TSFlagsFields = [];
+  list<int>    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;
 }
 
 
index b2e2125f82afdd2f6f0bde69426f92b405f4d1a0..7b3a5046c3c1d9349d9e6061ce00072f97a726c1 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "AsmWriterEmitter.h"
 #include "CodeGenTarget.h"
+#include "Record.h"
 #include <ostream>
 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";
 
index 85be70e650f52b8bf8d4e02b5ccab60c107f80f2..5e6af31635650f365c9f1b7b656829f3fab65248 100644 (file)
@@ -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
index e7ca857028054b0d774015d4a48e0c9734077a1f..9e52cbc39a20c1c0c67c965fce92f027a952c700 100644 (file)
@@ -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<Record*> 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");
index e711b8190c596ab405effbfafb800c50f92e326b..218fef8214675e024aadc49b855d0aef7d6d44a1 100644 (file)
@@ -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;