diff --git a/include/llvm/Target/MRegisterInfo.h b/include/llvm/Target/MRegisterInfo.h index 723ab69bd13..ea10c1cc47b 100644 --- a/include/llvm/Target/MRegisterInfo.h +++ b/include/llvm/Target/MRegisterInfo.h @@ -64,6 +64,7 @@ private: const vt_iterator VTs; const sc_iterator SubClasses; const sc_iterator SuperClasses; + const sc_iterator SubRegClasses; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const iterator RegsBegin, RegsEnd; public: @@ -71,8 +72,10 @@ public: const MVT::ValueType *vts, const TargetRegisterClass * const *subcs, const TargetRegisterClass * const *supcs, + const TargetRegisterClass * const *subregcs, unsigned RS, unsigned Al, iterator RB, iterator RE) : ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs), + SubRegClasses(subregcs), RegSize(RS), Alignment(Al), RegsBegin(RB), RegsEnd(RE) {} virtual ~TargetRegisterClass() {} // Allow subclasses @@ -167,6 +170,47 @@ public: return I; } + /// hasSubRegForClass - return true if the specified TargetRegisterClass is a + /// class of a sub-register class for this TargetRegisterClass. + bool hasSubRegForClass(const TargetRegisterClass *cs) const { + for (int i = 0; SubRegClasses[i] != NULL; ++i) + if (SubRegClasses[i] == cs) + return true; + return false; + } + + /// hasClassForSubReg - return true if the specified TargetRegisterClass is a + /// class of a sub-register class for this TargetRegisterClass. + bool hasClassForSubReg(unsigned SubReg) const { + --SubReg; + for (unsigned i = 0; SubRegClasses[i] != NULL; ++i) + if (i == SubReg) + return true; + return false; + } + + /// getClassForSubReg - return theTargetRegisterClass for the sub-register + /// at idx for this TargetRegisterClass. + sc_iterator getClassForSubReg(unsigned SubReg) const { + --SubReg; + for (unsigned i = 0; SubRegClasses[i] != NULL; ++i) + if (i == SubReg) + return &SubRegClasses[i]; + return NULL; + } + + /// subregclasses_begin / subregclasses_end - Loop over all of + /// the subregister classes of this register class. + sc_iterator subregclasses_begin() const { + return SubRegClasses; + } + + sc_iterator subregclasses_end() const { + sc_iterator I = SubRegClasses; + while (*I != NULL) ++I; + return I; + } + /// allocation_order_begin/end - These methods define a range of registers /// which specify the registers in this class that are valid to register /// allocate, and the preferred order to allocate them in. For example, diff --git a/lib/Target/Target.td b/lib/Target/Target.td index d646e28c1d1..4babef15747 100644 --- a/lib/Target/Target.td +++ b/lib/Target/Target.td @@ -109,6 +109,10 @@ class RegisterClass regTypes, int alignment, // allocation used by the register allocator. // list MemberList = regList; + + // SubClassList - Specify which register classes correspond to subregisters + // of this class. The order should be by subregister set index. + list SubRegClassList = []; // MethodProtos/MethodBodies - These members can be used to insert arbitrary // code into a generated register class. The normal usage of this is to diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 8e9008c74aa..83c85b8f3a9 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -38,6 +38,7 @@ namespace llvm { std::vector VTs; unsigned SpillSize; unsigned SpillAlignment; + std::vector SubRegClasses; std::string MethodProtos, MethodBodies; const std::string &getName() const; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index 17cea6f2a61..c3c1ac22717 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -199,6 +199,16 @@ CodeGenRegisterClass::CodeGenRegisterClass(Record *R) : TheDef(R) { Elements.push_back(Reg); } + std::vector SubRegClassList = + R->getValueAsListOfDefs("SubRegClassList"); + for (unsigned i = 0, e = SubRegClassList.size(); i != e; ++i) { + Record *SubRegClass = SubRegClassList[i]; + if (!SubRegClass->isSubClassOf("RegisterClass")) + throw "Register Class member '" + SubRegClass->getName() + + "' does not derive from the RegisterClass class!"; + SubRegClasses.push_back(SubRegClass); + } + // Allow targets to override the size in bits of the RegisterClass. unsigned Size = R->getValueAsInt("Size"); diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 5fbd013eaaf..a2269a83fc7 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -224,6 +224,44 @@ void RegisterInfoEmitter::run(std::ostream &OS) { std::map > SuperClassMap; OS << "\n"; + + + // Emit the sub-register classes for each RegisterClass + for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { + const CodeGenRegisterClass &RC = RegisterClasses[rc]; + + // Give the register class a legal C name if it's anonymous. + std::string Name = RC.TheDef->getName(); + + OS << " // " << Name + << " Sub-register Classess...\n" + << " static const TargetRegisterClass* const " + << Name << "SubRegClasses [] = {\n "; + + bool Empty = true; + + for (unsigned subrc = 0, e2 = RC.SubRegClasses.size(); + subrc != e2; ++subrc) { + unsigned rc2 = 0, e2 = RegisterClasses.size(); + for (; rc2 != e2; ++rc2) { + const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; + if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) { + if (!Empty) OS << ", "; + OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; + Empty = false; + break; + } + } + if (rc2 == e2) + throw "Register Class member '" + + RC.SubRegClasses[subrc]->getName() + + "' is not a valid RegisterClass!"; + } + + OS << (!Empty ? ", " : "") << "NULL"; + OS << "\n };\n\n"; + } + // Emit the sub-classes array for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { const CodeGenRegisterClass &RC = RegisterClasses[rc]; @@ -304,6 +342,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", " + << RC.getName() + "SubRegClasses" << ", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.getName() << ", " << RC.getName() << " + " << RC.Elements.size() << ") {}\n";