diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index c5dfb681018..65d45be0e79 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -111,6 +111,10 @@ struct MCRegisterDesc { uint32_t SubRegs; // Sub-register set, described above uint32_t SuperRegs; // Super-register set, described above + // Offset into MCRI::SubRegIndices of a list of sub-register indices for each + // sub-register in SubRegs. + uint32_t SubRegIndices; + // RegUnits - Points to the list of register units. The low 4 bits holds the // Scale, the high bits hold an offset into DiffLists. See MCRegUnitIterator. uint32_t RegUnits; @@ -305,9 +309,7 @@ public: /// getSubReg - Returns the physical register number of sub-register "Index" /// for physical register RegNo. Return zero if the sub-register does not /// exist. - unsigned getSubReg(unsigned Reg, unsigned Idx) const { - return *(SubRegIndices + (Reg - 1) * NumSubRegIndices + Idx - 1); - } + unsigned getSubReg(unsigned Reg, unsigned Idx) const; /// getMatchingSuperReg - Return a super-register of the specified register /// Reg so its sub-register of index SubIdx is Reg. @@ -317,12 +319,7 @@ public: /// getSubRegIndex - For a given register pair, return the sub-register index /// if the second register is a sub-register of the first. Return zero /// otherwise. - unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const { - for (unsigned I = 1; I <= NumSubRegIndices; ++I) - if (getSubReg(RegNo, I) == SubRegNo) - return I; - return 0; - } + unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; /// getName - Return the human-readable symbolic target-specific name for the /// specified physical register. @@ -442,10 +439,32 @@ public: inline unsigned MCRegisterInfo::getMatchingSuperReg(unsigned Reg, unsigned SubIdx, const MCRegisterClass *RC) const { - for (MCSuperRegIterator Supers(Reg, this); Supers.isValid(); ++Supers) - if (Reg == getSubReg(*Supers, SubIdx) && RC->contains(*Supers)) - return *Supers; - return 0; + for (MCSuperRegIterator Supers(Reg, this); Supers.isValid(); ++Supers) + if (RC->contains(*Supers) && Reg == getSubReg(*Supers, SubIdx)) + return *Supers; + return 0; +} + +inline +unsigned MCRegisterInfo::getSubReg(unsigned Reg, unsigned Idx) const { + // Get a pointer to the corresponding SubRegIndices list. This list has the + // name of each sub-register in the same order as MCSubRegIterator. + const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices; + for (MCSubRegIterator Subs(Reg, this); Subs.isValid(); ++Subs, ++SRI) + if (*SRI == Idx) + return *Subs; + return 0; +} + +inline +unsigned MCRegisterInfo::getSubRegIndex(unsigned Reg, unsigned SubReg) const { + // Get a pointer to the corresponding SubRegIndices list. This list has the + // name of each sub-register in the same order as MCSubRegIterator. + const uint16_t *SRI = SubRegIndices + get(Reg).SubRegIndices; + for (MCSubRegIterator Subs(Reg, this); Subs.isValid(); ++Subs, ++SRI) + if (*Subs == SubReg) + return *SRI; + return 0; } //===----------------------------------------------------------------------===// diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index b3cd7d670b8..b9138780aa8 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -484,7 +484,7 @@ static void printSimpleValueType(raw_ostream &OS, MVT::SimpleValueType VT) { } static void printSubRegIndex(raw_ostream &OS, const CodeGenSubRegIndex *Idx) { - OS << Idx->getQualifiedName(); + OS << Idx->EnumValue; } // Differentially encoded register and regunit lists allow for better @@ -555,6 +555,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, SmallVector RegUnitLists(Regs.size()); SmallVector RegUnitInitScale(Regs.size()); + // Keep track of sub-register names as well. These are not differentially + // encoded. + typedef SmallVector SubRegIdxVec; + SequenceToOffsetTable SubRegIdxSeqs; + SmallVector SubRegIdxLists(Regs.size()); + SequenceToOffsetTable RegStrings; // Precompute register lists for the SequenceToOffsetTable. @@ -569,6 +575,12 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, diffEncode(SubRegLists[i], Reg->EnumValue, SR.begin(), SR.end()); DiffSeqs.add(SubRegLists[i]); + // Compute the corresponding sub-register indexes. + SubRegIdxVec &SRIs = SubRegIdxLists[i]; + for (unsigned j = 0, je = SR.size(); j != je; ++j) + SRIs.push_back(Reg->getSubRegIndex(SR[j])); + SubRegIdxSeqs.add(SRIs); + // Super-registers are already computed. const RegVec &SuperRegList = Reg->getSuperRegs(); diffEncode(SuperRegLists[i], Reg->EnumValue, @@ -612,6 +624,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, // Compute the final layout of the sequence table. DiffSeqs.layout(); + SubRegIdxSeqs.layout(); OS << "namespace llvm {\n\n"; @@ -622,6 +635,11 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, DiffSeqs.emit(OS, printDiff16); OS << "};\n\n"; + // Emit the table of sub-register indexes. + OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[] = {\n"; + SubRegIdxSeqs.emit(OS, printSubRegIndex); + OS << "};\n\n"; + // Emit the string table. RegStrings.layout(); OS << "extern const char " << TargetName << "RegStrings[] = {\n"; @@ -630,7 +648,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[] = { // Descriptors\n"; - OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0 },\n"; + OS << " { " << RegStrings.get("") << ", 0, 0, 0, 0, 0 },\n"; // Emit the register descriptors now. for (unsigned i = 0, e = Regs.size(); i != e; ++i) { @@ -639,6 +657,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << DiffSeqs.get(OverlapLists[i]) << ", " << DiffSeqs.get(SubRegLists[i]) << ", " << DiffSeqs.get(SuperRegLists[i]) << ", " + << SubRegIdxSeqs.get(SubRegIdxLists[i]) << ", " << (DiffSeqs.get(RegUnitLists[i])*16 + RegUnitInitScale[i]) << " },\n"; } OS << "};\n\n"; // End of register descriptors... @@ -718,37 +737,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "};\n\n"; - // Emit the data table for getSubReg(). ArrayRef SubRegIndices = RegBank.getSubRegIndices(); - if (SubRegIndices.size()) { - OS << "const uint16_t " << TargetName << "SubRegTable[][" - << SubRegIndices.size() << "] = {\n"; - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs(); - OS << " /* " << Regs[i]->TheDef->getName() << " */\n"; - if (SRM.empty()) { - OS << " {0},\n"; - continue; - } - OS << " {"; - for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) { - // FIXME: We really should keep this to 80 columns... - CodeGenRegister::SubRegMap::const_iterator SubReg = - SRM.find(SubRegIndices[j]); - if (SubReg != SRM.end()) - OS << getQualifiedName(SubReg->second->TheDef); - else - OS << "0"; - if (j != je - 1) - OS << ", "; - } - OS << "}" << (i != e ? "," : "") << "\n"; - } - OS << "};\n\n"; - OS << "const uint16_t *get" << TargetName - << "SubRegTable() {\n return (const uint16_t *)" << TargetName - << "SubRegTable;\n}\n\n"; - } EmitRegMappingTables(OS, Regs, false); @@ -772,21 +761,17 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, // MCRegisterInfo initialization routine. OS << "static inline void Init" << TargetName << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " - << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n"; - OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " + << "unsigned DwarfFlavour = 0, unsigned EHFlavour = 0) {\n" + << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ", " << TargetName << "RegUnitRoots, " << RegBank.getNumNativeRegUnits() << ", " << TargetName << "RegDiffLists, " - << TargetName << "RegStrings, "; - if (SubRegIndices.size() != 0) - OS << "(uint16_t*)" << TargetName << "SubRegTable, " - << SubRegIndices.size() << ",\n"; - else - OS << "NULL, 0,\n"; - - OS << " " << TargetName << "RegEncodingTable);\n\n"; + << TargetName << "RegStrings, " + << TargetName << "SubRegIdxLists, " + << SubRegIndices.size() << ",\n" + << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, false); @@ -1139,9 +1124,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const uint16_t " << TargetName << "RegDiffLists[];\n"; OS << "extern const char " << TargetName << "RegStrings[];\n"; OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n"; - if (SubRegIndices.size() != 0) - OS << "extern const uint16_t *get" << TargetName - << "SubRegTable();\n"; + OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n"; OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n"; EmitRegMappingTables(OS, Regs, true); @@ -1158,14 +1141,9 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " " << RegBank.getNumNativeRegUnits() << ",\n" << " " << TargetName << "RegDiffLists,\n" << " " << TargetName << "RegStrings,\n" - << " "; - if (SubRegIndices.size() != 0) - OS << "get" << TargetName << "SubRegTable(), " - << SubRegIndices.size() << ",\n"; - else - OS << "NULL, 0,\n"; - - OS << " " << TargetName << "RegEncodingTable);\n\n"; + << " " << TargetName << "SubRegIdxLists,\n" + << " " << SubRegIndices.size() << ",\n" + << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, true);