mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-09 11:25:55 +00:00
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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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";
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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");
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user