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
This commit is contained in:
Chris Lattner
2004-08-14 22:50:53 +00:00
parent ca068e861b
commit 175580c0f3
5 changed files with 70 additions and 23 deletions

View 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 /// ops definition - This is just a simple marker used to identify the operands
/// list for an instruction. This should be used like this: /// list for an instruction. This should be used like this:
/// (ops R32:$dst, R32:$src) or something similar. /// (ops R32:$dst, R32:$src) or something similar.
@@ -166,6 +152,40 @@ def i16imm : Operand<i16>;
def i32imm : Operand<i32>; def i32imm : Operand<i32>;
def i64imm : Operand<i64>; 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 // Target - This class contains the "global" target information
// //
@@ -178,8 +198,11 @@ class Target {
// this target. Typically this is an i32 or i64 type. // this target. Typically this is an i32 or i64 type.
ValueType PointerType; ValueType PointerType;
// InstructionSet - Instruction set description for this target // InstructionSet - Instruction set description for this target.
InstrInfo InstructionSet; InstrInfo InstructionSet;
// AssemblyWriter - The AsmWriter instance to use for this target.
AsmWriter AssemblyWriter = DefaultAsmWriter;
} }

View File

@@ -14,6 +14,7 @@
#include "AsmWriterEmitter.h" #include "AsmWriterEmitter.h"
#include "CodeGenTarget.h" #include "CodeGenTarget.h"
#include "Record.h"
#include <ostream> #include <ostream>
using namespace llvm; using namespace llvm;
@@ -28,13 +29,19 @@ void AsmWriterEmitter::run(std::ostream &O) {
EmitSourceFileHeader("Assembly Writer Source Fragment", O); EmitSourceFileHeader("Assembly Writer Source Fragment", O);
CodeGenTarget Target; CodeGenTarget Target;
Record *AsmWriter = Target.getAsmWriter();
std::string AsmWriterClassName =
AsmWriter->getValueAsString("AsmWriterClassName");
O << O <<
"/// printInstruction - This method is automatically generated by tablegen\n" "/// printInstruction - This method is automatically generated by tablegen\n"
"/// from the instruction set description. This method returns true if the\n" "/// from the instruction set description. This method returns true if the\n"
"/// machine instruction was sufficiently described to print it, otherwise\n" "/// machine instruction was sufficiently described to print it, otherwise\n"
"/// it returns false.\n" "/// it returns false.\n"
"bool " << Target.getName() "bool " << Target.getName() << AsmWriterClassName
<< "AsmPrinter::printInstruction(const MachineInstr *MI) {\n"; << "::printInstruction(const MachineInstr *MI) {\n";
O << " switch (MI->getOpcode()) {\n" O << " switch (MI->getOpcode()) {\n"
" default: return false;\n"; " default: return false;\n";

View File

@@ -74,7 +74,7 @@ namespace llvm {
bool isTwoAddress; bool isTwoAddress;
bool isTerminator; bool isTerminator;
CodeGenInstruction(Record *R); CodeGenInstruction(Record *R, const std::string &AsmStr);
/// getOperandNamed - Return the index of the operand with the specified /// getOperandNamed - Return the index of the operand with the specified
/// non-empty name. If the instruction does not have an operand with the /// non-empty name. If the instruction does not have an operand with the

View File

@@ -97,14 +97,27 @@ Record *CodeGenTarget::getInstructionSet() const {
return TargetRec->getValueAsDef("InstructionSet"); return TargetRec->getValueAsDef("InstructionSet");
} }
/// getAsmWriter - Return the AssemblyWriter definition for this target.
///
Record *CodeGenTarget::getAsmWriter() const {
return TargetRec->getValueAsDef("AssemblyWriter");
}
void CodeGenTarget::ReadInstructions() const { void CodeGenTarget::ReadInstructions() const {
std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction"); std::vector<Record*> Insts = Records.getAllDerivedDefinitions("Instruction");
if (Insts.size() == 0) if (Insts.size() == 0)
throw std::string("No 'Instruction' subclasses defined!"); throw std::string("No 'Instruction' subclasses defined!");
for (unsigned i = 0, e = Insts.size(); i != e; ++i) std::string InstFormatName =
Instructions.insert(std::make_pair(Insts[i]->getName(), Insts[i])); 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. /// getPHIInstruction - Return the designated PHI instruction.
@@ -117,10 +130,10 @@ const CodeGenInstruction &CodeGenTarget::getPHIInstruction() const {
return I->second; 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"); Name = R->getValueAsString("Name");
Namespace = R->getValueAsString("Namespace"); Namespace = R->getValueAsString("Namespace");
AsmString = R->getValueAsString("AsmString");
isReturn = R->getValueAsBit("isReturn"); isReturn = R->getValueAsBit("isReturn");
isBranch = R->getValueAsBit("isBranch"); isBranch = R->getValueAsBit("isBranch");

View File

@@ -56,10 +56,14 @@ public:
MVT::ValueType getPointerType() const { return PointerType; } MVT::ValueType getPointerType() const { return PointerType; }
// getInstructionSet - Return the InstructionSet object. /// getInstructionSet - Return the InstructionSet object.
/// ///
Record *getInstructionSet() const; Record *getInstructionSet() const;
/// getAsmWriter - Return the AssemblyWriter definition for this target.
///
Record *getAsmWriter() const;
/// getPHIInstruction - Return the designated PHI instruction. /// getPHIInstruction - Return the designated PHI instruction.
const CodeGenInstruction &getPHIInstruction() const; const CodeGenInstruction &getPHIInstruction() const;