diff options
-rw-r--r-- | include/llvm/MC/MCRegisterInfo.h | 18 | ||||
-rw-r--r-- | include/llvm/Target/Target.td | 19 | ||||
-rw-r--r-- | lib/MC/MCRegisterInfo.cpp | 13 | ||||
-rw-r--r-- | lib/Target/ARM/ARMRegisterInfo.td | 46 | ||||
-rw-r--r-- | lib/Target/SystemZ/SystemZRegisterInfo.td | 2 | ||||
-rw-r--r-- | lib/Target/X86/X86RegisterInfo.td | 10 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.cpp | 8 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 13 | ||||
-rw-r--r-- | utils/TableGen/RegisterInfoEmitter.cpp | 20 |
9 files changed, 113 insertions, 36 deletions
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index 0c4a53f..002f71d 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -144,6 +144,13 @@ public: bool operator<(DwarfLLVMRegPair RHS) const { return FromReg < RHS.FromReg; } }; + + /// SubRegCoveredBits - Emitted by tablegen: bit range covered by a subreg + /// index, -1 in any being invalid. + struct SubRegCoveredBits { + uint16_t Offset; + uint16_t Size; + }; private: const MCRegisterDesc *Desc; // Pointer to the descriptor array unsigned NumRegs; // Number of entries in the array @@ -157,6 +164,8 @@ private: const char *RegStrings; // Pointer to the string table. const uint16_t *SubRegIndices; // Pointer to the subreg lookup // array. + const SubRegCoveredBits *SubRegIdxRanges; // Pointer to the subreg covered + // bit ranges array. unsigned NumSubRegIndices; // Number of subreg indices. const uint16_t *RegEncodingTable; // Pointer to array of register // encodings. @@ -236,6 +245,7 @@ public: const char *Strings, const uint16_t *SubIndices, unsigned NumIndices, + const SubRegCoveredBits *SubIdxRanges, const uint16_t *RET) { Desc = D; NumRegs = NR; @@ -249,6 +259,7 @@ public: NumRegUnits = NRU; SubRegIndices = SubIndices; NumSubRegIndices = NumIndices; + SubRegIdxRanges = SubIdxRanges; RegEncodingTable = RET; } @@ -327,6 +338,13 @@ public: /// otherwise. unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const; + /// \brief Get the bit range covered by a given sub-register index. + /// In some cases, for instance non-contiguous synthesized indices, + /// there is no meaningful bit range to get, so return true if \p Offset + /// and \p Size were set. + bool getSubRegIdxCoveredBits(unsigned Idx, + unsigned &Offset, unsigned &Size) const; + /// \brief Return the human-readable symbolic target-specific name for the /// specified physical register. const char *getName(unsigned RegNo) const { diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 7de8b38..c201f6b 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -22,12 +22,19 @@ include "llvm/IR/Intrinsics.td" class RegisterClass; // Forward def // SubRegIndex - Use instances of SubRegIndex to identify subregisters. -class SubRegIndex<list<SubRegIndex> comps = []> { +class SubRegIndex<int size = -1, int offset = 0> { string Namespace = ""; + // Size - Size (in bits) of the sub-registers represented by this index. + int Size = size; + + // Offset - Offset of the first bit that is part of this sub-register index. + int Offset = offset; + // ComposedOf - A list of two SubRegIndex instances, [A, B]. // This indicates that this SubRegIndex is the result of composing A and B. - list<SubRegIndex> ComposedOf = comps; + // See ComposedSubRegIndex. + list<SubRegIndex> ComposedOf = []; // CoveringSubRegIndices - A list of two or more sub-register indexes that // cover this sub-register. @@ -48,6 +55,14 @@ class SubRegIndex<list<SubRegIndex> comps = []> { list<SubRegIndex> CoveringSubRegIndices = []; } +// ComposedSubRegIndex - A sub-register that is the result of composing A and B. +// Offset is set to the sum of A and B's Offsets. Size is set to B's Size. +class ComposedSubRegIndex<SubRegIndex A, SubRegIndex B> + : SubRegIndex<B.Size, -1> { + // See SubRegIndex. + let ComposedOf = [A, B]; +} + // RegAltNameIndex - The alternate name set to use for register operands of // this register class when printing. class RegAltNameIndex { diff --git a/lib/MC/MCRegisterInfo.cpp b/lib/MC/MCRegisterInfo.cpp index 5c71106..06d6d96 100644 --- a/lib/MC/MCRegisterInfo.cpp +++ b/lib/MC/MCRegisterInfo.cpp @@ -46,6 +46,19 @@ unsigned MCRegisterInfo::getSubRegIndex(unsigned Reg, unsigned SubReg) const { return 0; } +bool MCRegisterInfo::getSubRegIdxCoveredBits(unsigned Idx, unsigned &Offset, + unsigned &Size) const { + assert(Idx && Idx < getNumSubRegIndices() && + "This is not a subregister index"); + // Get a pointer to the corresponding SubRegIdxRanges struct. + const SubRegCoveredBits *Bits = &SubRegIdxRanges[Idx]; + if (Bits->Offset == (uint16_t)-1 || Bits->Size == (uint16_t)-1) + return false; + Offset = Bits->Offset; + Size = Bits->Size; + return true; +} + int MCRegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const { const DwarfLLVMRegPair *M = isEH ? EHL2DwarfRegs : L2DwarfRegs; unsigned Size = isEH ? EHL2DwarfRegsSize : L2DwarfRegsSize; diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index 85743d8..3ffe0e9 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -27,31 +27,31 @@ class ARMFReg<bits<16> Enc, string n> : Register<n> { // Subregister indices. let Namespace = "ARM" in { -def qqsub_0 : SubRegIndex; -def qqsub_1 : SubRegIndex; +def qqsub_0 : SubRegIndex<256>; +def qqsub_1 : SubRegIndex<256, 256>; // Note: Code depends on these having consecutive numbers. -def qsub_0 : SubRegIndex; -def qsub_1 : SubRegIndex; -def qsub_2 : SubRegIndex<[qqsub_1, qsub_0]>; -def qsub_3 : SubRegIndex<[qqsub_1, qsub_1]>; - -def dsub_0 : SubRegIndex; -def dsub_1 : SubRegIndex; -def dsub_2 : SubRegIndex<[qsub_1, dsub_0]>; -def dsub_3 : SubRegIndex<[qsub_1, dsub_1]>; -def dsub_4 : SubRegIndex<[qsub_2, dsub_0]>; -def dsub_5 : SubRegIndex<[qsub_2, dsub_1]>; -def dsub_6 : SubRegIndex<[qsub_3, dsub_0]>; -def dsub_7 : SubRegIndex<[qsub_3, dsub_1]>; - -def ssub_0 : SubRegIndex; -def ssub_1 : SubRegIndex; -def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>; -def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>; - -def gsub_0 : SubRegIndex; -def gsub_1 : SubRegIndex; +def qsub_0 : SubRegIndex<128>; +def qsub_1 : SubRegIndex<128, 128>; +def qsub_2 : ComposedSubRegIndex<qqsub_1, qsub_0>; +def qsub_3 : ComposedSubRegIndex<qqsub_1, qsub_1>; + +def dsub_0 : SubRegIndex<64>; +def dsub_1 : SubRegIndex<64, 64>; +def dsub_2 : ComposedSubRegIndex<qsub_1, dsub_0>; +def dsub_3 : ComposedSubRegIndex<qsub_1, dsub_1>; +def dsub_4 : ComposedSubRegIndex<qsub_2, dsub_0>; +def dsub_5 : ComposedSubRegIndex<qsub_2, dsub_1>; +def dsub_6 : ComposedSubRegIndex<qsub_3, dsub_0>; +def dsub_7 : ComposedSubRegIndex<qsub_3, dsub_1>; + +def ssub_0 : SubRegIndex<32>; +def ssub_1 : SubRegIndex<32, 32>; +def ssub_2 : ComposedSubRegIndex<dsub_1, ssub_0>; +def ssub_3 : ComposedSubRegIndex<dsub_1, ssub_1>; + +def gsub_0 : SubRegIndex<32>; +def gsub_1 : SubRegIndex<32, 32>; // Let TableGen synthesize the remaining 12 ssub_* indices. // We don't need to name them. } diff --git a/lib/Target/SystemZ/SystemZRegisterInfo.td b/lib/Target/SystemZ/SystemZRegisterInfo.td index 7e4f0b9..7795fff 100644 --- a/lib/Target/SystemZ/SystemZRegisterInfo.td +++ b/lib/Target/SystemZ/SystemZRegisterInfo.td @@ -24,7 +24,7 @@ let Namespace = "SystemZ" in { def subreg_32bit : SubRegIndex; // could also be known as "subreg_high32" def subreg_high : SubRegIndex; def subreg_low : SubRegIndex; -def subreg_low32 : SubRegIndex<[subreg_low, subreg_32bit]>; +def subreg_low32 : ComposedSubRegIndex<subreg_low, subreg_32bit>; } // Define a register class that contains values of type TYPE and an diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index be6282a..edf22ee 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -21,11 +21,11 @@ class X86Reg<string n, bits<16> Enc, list<Register> subregs = []> : Register<n> // Subregister indices. let Namespace = "X86" in { - def sub_8bit : SubRegIndex; - def sub_8bit_hi : SubRegIndex; - def sub_16bit : SubRegIndex; - def sub_32bit : SubRegIndex; - def sub_xmm : SubRegIndex; + def sub_8bit : SubRegIndex<8>; + def sub_8bit_hi : SubRegIndex<8, 8>; + def sub_16bit : SubRegIndex<16>; + def sub_32bit : SubRegIndex<32>; + def sub_xmm : SubRegIndex<64>; } //===----------------------------------------------------------------------===// diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 9d72d0d..3eed3ff 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -32,12 +32,14 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum) Name = R->getName(); if (R->getValue("Namespace")) Namespace = R->getValueAsString("Namespace"); + Size = R->getValueAsInt("Size"); + Offset = R->getValueAsInt("Offset"); } CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum) - : TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum), - LaneMask(0), AllSuperRegsCovered(true) { + : TheDef(0), Name(N), Namespace(Nspace), Size(-1), Offset(-1), + EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) { } std::string CodeGenSubRegIndex::getQualifiedName() const { @@ -69,7 +71,7 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) { if (!Parts.empty()) { if (Parts.size() < 2) PrintFatalError(TheDef->getLoc(), - "CoveredBySubRegs must have two or more entries"); + "CoveredBySubRegs must have two or more entries"); SmallVector<CodeGenSubRegIndex*, 8> IdxParts; for (unsigned i = 0, e = Parts.size(); i != e; ++i) IdxParts.push_back(RegBank.getSubRegIdx(Parts[i])); diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index ba62db4..c834551 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -37,6 +37,8 @@ namespace llvm { Record *const TheDef; std::string Name; std::string Namespace; + uint16_t Size; + uint16_t Offset; public: const unsigned EnumValue; @@ -52,6 +54,8 @@ namespace llvm { const std::string &getName() const { return Name; } const std::string &getNamespace() const { return Namespace; } std::string getQualifiedName() const; + uint16_t getSize() const { return Size; } + uint16_t getOffset() const { return Offset; } // Order CodeGenSubRegIndex pointers by EnumValue. struct Less { @@ -79,6 +83,15 @@ namespace llvm { assert(A && B); std::pair<CompMap::iterator, bool> Ins = Composed.insert(std::make_pair(A, B)); + // Synthetic subreg indices that aren't contiguous (for instance ARM + // register tuples) don't have a bit range, so it's OK to let + // B->Offset == -1. For the other cases, accumulate the offset and set + // the size here. Only do so if there is no offset yet though. + if ((Offset != (uint16_t)-1 && A->Offset != (uint16_t)-1) && + (B->Offset == (uint16_t)-1)) { + B->Offset = Offset + A->Offset; + B->Size = A->Size; + } return (Ins.second || Ins.first->second == B) ? 0 : Ins.first->second; } diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 2907c33..9978237 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -703,6 +703,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters(); + ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices(); // The lists of sub-registers and super-registers go in the same array. That // allows us to share suffixes. typedef std::vector<const CodeGenRegister*> RegVec; @@ -790,6 +791,19 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, SubRegIdxSeqs.emit(OS, printSubRegIndex); OS << "};\n\n"; + // Emit the table of sub-register index sizes. + OS << "extern const MCRegisterInfo::SubRegCoveredBits " + << TargetName << "SubRegIdxRanges[] = {\n"; + OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n"; + for (ArrayRef<CodeGenSubRegIndex*>::const_iterator + SRI = SubRegIndices.begin(), SRE = SubRegIndices.end(); + SRI != SRE; ++SRI) { + OS << " { " << (*SRI)->getOffset() << ", " + << (*SRI)->getSize() + << " },\t// " << (*SRI)->getName() << "\n"; + } + OS << "};\n\n"; + // Emit the string table. RegStrings.layout(); OS << "extern const char " << TargetName << "RegStrings[] = {\n"; @@ -886,8 +900,6 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "};\n\n"; - ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices(); - EmitRegMappingTables(OS, Regs, false); // Emit Reg encoding table @@ -920,6 +932,7 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, << TargetName << "RegStrings, " << TargetName << "SubRegIdxLists, " << (SubRegIndices.size() + 1) << ",\n" + << TargetName << "SubRegIdxRanges, " << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, false); @@ -1251,6 +1264,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const char " << TargetName << "RegStrings[];\n"; OS << "extern const uint16_t " << TargetName << "RegUnitRoots[][2];\n"; OS << "extern const uint16_t " << TargetName << "SubRegIdxLists[];\n"; + OS << "extern const MCRegisterInfo::SubRegCoveredBits " + << TargetName << "SubRegIdxRanges[];\n"; OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n"; EmitRegMappingTables(OS, Regs, true); @@ -1271,6 +1286,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, << " " << TargetName << "RegStrings,\n" << " " << TargetName << "SubRegIdxLists,\n" << " " << SubRegIndices.size() + 1 << ",\n" + << " " << TargetName << "SubRegIdxRanges,\n" << " " << TargetName << "RegEncodingTable);\n\n"; EmitRegMapping(OS, Regs, true); |