summaryrefslogtreecommitdiff
path: root/utils/TableGen/RegisterInfoEmitter.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2011-12-19 16:53:34 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2011-12-19 16:53:34 +0000
commit570f9a972e02830d1ca223743dd6b4cc4fdf9549 (patch)
treeff67aae70fb2690c391b75f7ec47ff5a4fc5c55c /utils/TableGen/RegisterInfoEmitter.cpp
parenta9f65b9a1f57dcf546399ac32bf89d71d20df5b9 (diff)
downloadllvm-570f9a972e02830d1ca223743dd6b4cc4fdf9549.tar.gz
llvm-570f9a972e02830d1ca223743dd6b4cc4fdf9549.tar.bz2
llvm-570f9a972e02830d1ca223743dd6b4cc4fdf9549.tar.xz
Emit a getMatchingSuperRegClass() implementation for every target.
Use information computed while inferring new register classes to emit accurate, table-driven implementations of getMatchingSuperRegClass(). Delete the old manual, error-prone implementations in the targets. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146873 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils/TableGen/RegisterInfoEmitter.cpp')
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp48
1 files changed, 48 insertions, 0 deletions
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index d228f72cf3..5fa2fe0d62 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -426,6 +426,9 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
<< " unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
<< " const TargetRegisterClass *"
"getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n"
+ << " const TargetRegisterClass *getMatchingSuperRegClass("
+ "const TargetRegisterClass*, const TargetRegisterClass*, "
+ "unsigned) const;\n"
<< "};\n\n";
const std::vector<Record*> &SubRegIndices = RegBank.getSubRegIndices();
@@ -815,6 +818,51 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
}
OS << "}\n\n";
+ // Emit getMatchingSuperRegClass.
+ OS << "const TargetRegisterClass *" << ClassName
+ << "::getMatchingSuperRegClass(const TargetRegisterClass *A,"
+ " const TargetRegisterClass *B, unsigned Idx) const {\n";
+ if (SubRegIndices.empty()) {
+ OS << " llvm_unreachable(\"Target has no sub-registers\");\n";
+ } else {
+ // We need to find the largest sub-class of A such that every register has
+ // an Idx sub-register in B. Map (B, Idx) to a bit-vector of
+ // super-register classes that map into B. Then compute the largest common
+ // sub-class with A by taking advantage of the register class ordering,
+ // like getCommonSubClass().
+
+ // Bitvector table is NumRCs x NumSubIndexes x BVWords, where BVWords is
+ // the number of 32-bit words required to represent all register classes.
+ const unsigned BVWords = (RegisterClasses.size()+31)/32;
+ BitVector BV(RegisterClasses.size());
+
+ OS << " static const unsigned Table[" << RegisterClasses.size()
+ << "][" << SubRegIndices.size() << "][" << BVWords << "] = {\n";
+ for (unsigned rci = 0, rce = RegisterClasses.size(); rci != rce; ++rci) {
+ const CodeGenRegisterClass &RC = *RegisterClasses[rci];
+ OS << " {\t// " << RC.getName() << "\n";
+ for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
+ Record *Idx = SubRegIndices[sri];
+ BV.reset();
+ RC.getSuperRegClasses(Idx, BV);
+ OS << " { ";
+ printBitVectorAsHex(OS, BV, 32);
+ OS << "},\t// " << Idx->getName() << '\n';
+ }
+ OS << " },\n";
+ }
+ OS << " };\n assert(A && B && \"Missing regclass\");\n"
+ << " --Idx;\n"
+ << " assert(Idx < " << SubRegIndices.size() << " && \"Bad subreg\");\n"
+ << " const unsigned *TV = Table[B->getID()][Idx];\n"
+ << " const unsigned *SC = A->getSubClassMask();\n"
+ << " for (unsigned i = 0; i != " << BVWords << "; ++i)\n"
+ << " if (unsigned Common = TV[i] & SC[i])\n"
+ << " return getRegClass(32*i + CountTrailingZeros_32(Common));\n"
+ << " return 0;\n";
+ }
+ OS << "}\n\n";
+
// Emit the constructor of the class...
OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";