aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/Target.td18
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp31
2 files changed, 40 insertions, 9 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index 24be2b1..cc76714 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -28,6 +28,24 @@ class SubRegIndex<list<SubRegIndex> comps = []> {
// 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;
+
+ // CoveringSubRegIndices - A list of two or more sub-register indexes that
+ // cover this sub-register.
+ //
+ // This field should normally be left blank as TableGen can infer it.
+ //
+ // TableGen automatically detects sub-registers that straddle the registers
+ // in the SubRegs field of a Register definition. For example:
+ //
+ // Q0 = dsub_0 -> D0, dsub_1 -> D1
+ // Q1 = dsub_0 -> D2, dsub_1 -> D3
+ // D1_D2 = dsub_0 -> D1, dsub_1 -> D2
+ // QQ0 = qsub_0 -> Q0, qsub_1 -> Q1
+ //
+ // TableGen will infer that D1_D2 is a sub-register of QQ0. It will be given
+ // the synthetic index dsub_1_dsub_2 unless some SubRegIndex is defined with
+ // CoveringSubRegIndices = [dsub_1, dsub_2].
+ list<SubRegIndex> CoveringSubRegIndices = [];
}
// RegAltNameIndex - The alternate name set to use for register operands of
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp
index 06df7ec..011f4b7 100644
--- a/utils/TableGen/CodeGenRegisters.cpp
+++ b/utils/TableGen/CodeGenRegisters.cpp
@@ -50,16 +50,29 @@ std::string CodeGenSubRegIndex::getQualifiedName() const {
void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) {
if (!TheDef)
return;
+
std::vector<Record*> Comps = TheDef->getValueAsListOfDefs("ComposedOf");
- if (Comps.empty())
- return;
- if (Comps.size() != 2)
- throw TGError(TheDef->getLoc(), "ComposedOf must have exactly two entries");
- CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]);
- CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]);
- CodeGenSubRegIndex *X = A->addComposite(B, this);
- if (X)
- throw TGError(TheDef->getLoc(), "Ambiguous ComposedOf entries");
+ if (!Comps.empty()) {
+ if (Comps.size() != 2)
+ throw TGError(TheDef->getLoc(), "ComposedOf must have exactly two entries");
+ CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]);
+ CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]);
+ CodeGenSubRegIndex *X = A->addComposite(B, this);
+ if (X)
+ throw TGError(TheDef->getLoc(), "Ambiguous ComposedOf entries");
+ }
+
+ std::vector<Record*> Parts =
+ TheDef->getValueAsListOfDefs("CoveringSubRegIndices");
+ if (!Parts.empty()) {
+ if (Parts.size() < 2)
+ throw TGError(TheDef->getLoc(),
+ "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]));
+ RegBank.addConcatSubRegIndex(IdxParts, this);
+ }
}
void CodeGenSubRegIndex::cleanComposites() {