aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/MC/MCRegisterInfo.h18
-rw-r--r--include/llvm/Target/Target.td19
-rw-r--r--lib/MC/MCRegisterInfo.cpp13
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.td46
-rw-r--r--lib/Target/SystemZ/SystemZRegisterInfo.td2
-rw-r--r--lib/Target/X86/X86RegisterInfo.td10
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp8
-rw-r--r--utils/TableGen/CodeGenRegisters.h13
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp20
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);