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:
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
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,
// allocation used by the register allocator.
//
list<Register> MemberList = regList;
+
+ // SubClassList - Specify which register classes correspond to subregisters
+ // of this class. The order should be by subregister set index.
+ list<RegisterClass> SubRegClassList = [];
// MethodProtos/MethodBodies - These members can be used to insert arbitrary
// code into a generated register class. The normal usage of this is to
std::vector<MVT::ValueType> VTs;
unsigned SpillSize;
unsigned SpillAlignment;
+ std::vector<Record*> SubRegClasses;
std::string MethodProtos, MethodBodies;
const std::string &getName() const;
Elements.push_back(Reg);
}
+ std::vector<Record*> 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");
std::map<unsigned, std::set<unsigned> > 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];
<< 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";