summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2012-05-15 17:35:57 +0000
committerJim Grosbach <grosbach@apple.com>2012-05-15 17:35:57 +0000
commit0ee07e013095e8c298fbcc5203e0bc9f334e15e1 (patch)
tree1e7b851af5c6f95999cb9e9fc48c0761575d5b7a
parent918f55fe239f00651e396be841f2b3b6e242f98d (diff)
TableGen'erate mapping physical registers to encoding values.
Many targets always use the same bitwise encoding value for physical registers in all (or most) instructions. Add this mapping to the .td files and TableGen'erate the information and expose an accessor in MCRegisterInfo. patch by Tom Stellard. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156829 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/MC/MCRegisterInfo.h14
-rw-r--r--include/llvm/Target/Target.td3
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp30
3 files changed, 42 insertions, 5 deletions
diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h
index 27acf2f2cc2..47f57495c15 100644
--- a/include/llvm/MC/MCRegisterInfo.h
+++ b/include/llvm/MC/MCRegisterInfo.h
@@ -146,6 +146,8 @@ private:
const uint16_t *SubRegIndices; // Pointer to the subreg lookup
// array.
unsigned NumSubRegIndices; // Number of subreg indices.
+ const uint16_t *RegEncodingTable; // Pointer to array of register
+ // encodings.
unsigned L2DwarfRegsSize;
unsigned EHL2DwarfRegsSize;
@@ -164,7 +166,8 @@ public:
const MCRegisterClass *C, unsigned NC,
const uint16_t *RL,
const uint16_t *SubIndices,
- unsigned NumIndices) {
+ unsigned NumIndices,
+ const uint16_t *RET) {
Desc = D;
NumRegs = NR;
RAReg = RA;
@@ -173,6 +176,7 @@ public:
NumClasses = NC;
SubRegIndices = SubIndices;
NumSubRegIndices = NumIndices;
+ RegEncodingTable = RET;
}
/// mapLLVMRegsToDwarfRegs - Used to initialize LLVM register to Dwarf
@@ -354,6 +358,14 @@ public:
assert(i < getNumRegClasses() && "Register Class ID out of range");
return Classes[i];
}
+
+ /// getEncodingValue - Returns the encoding for RegNo
+ uint16_t getEncodingValue(unsigned RegNo) const {
+ assert(RegNo < NumRegs &&
+ "Attempting to get encoding for invalid register number!");
+ return RegEncodingTable[RegNo];
+ }
+
};
} // End llvm namespace
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index bd959d067fc..1f2bd470b7e 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -96,6 +96,9 @@ class Register<string n, list<string> altNames = []> {
// x86 register AX is covered by its sub-registers AL and AH, but EAX is not
// covered by its sub-register AX.
bit CoveredBySubRegs = 0;
+
+ // HWEncoding - The target specific hardware encoding for this register.
+ bits<16> HWEncoding = 0;
}
// RegisterWithSubRegs - This can be used to define instances of Register which
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 5b4a876e1bf..98bb611126e 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -636,6 +636,23 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
EmitRegMappingTables(OS, Regs, false);
+ // Emit Reg encoding table
+ OS << "extern const uint16_t " << TargetName;
+ OS << "RegEncodingTable[] = {\n";
+ // Add entry for NoRegister
+ OS << " 0,\n";
+ for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
+ Record *Reg = Regs[i]->TheDef;
+ BitsInit *BI = Reg->getValueAsBitsInit("HWEncoding");
+ uint64_t Value = 0;
+ for (unsigned b = 0, be = BI->getNumBits(); b != be; ++b) {
+ if (BitInit *B = dynamic_cast<BitInit*>(BI->getBit(b)))
+ Value |= (uint64_t)B->getValue() << b;
+ }
+ OS << " " << Value << ",\n";
+ }
+ OS << "};\n"; // End of HW encoding table
+
// MCRegisterInfo initialization routine.
OS << "static inline void Init" << TargetName
<< "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, "
@@ -645,9 +662,11 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target,
<< RegisterClasses.size() << ", " << TargetName << "RegLists, ";
if (SubRegIndices.size() != 0)
OS << "(uint16_t*)" << TargetName << "SubRegTable, "
- << SubRegIndices.size() << ");\n\n";
+ << SubRegIndices.size() << ",\n";
else
- OS << "NULL, 0);\n\n";
+ OS << "NULL, 0,\n";
+
+ OS << " " << TargetName << "RegEncodingTable);\n\n";
EmitRegMapping(OS, Regs, false);
@@ -1001,6 +1020,7 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
if (SubRegIndices.size() != 0)
OS << "extern const uint16_t *get" << TargetName
<< "SubRegTable();\n";
+ OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";
EmitRegMappingTables(OS, Regs, true);
@@ -1016,9 +1036,11 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
<< " ";
if (SubRegIndices.size() != 0)
OS << "get" << TargetName << "SubRegTable(), "
- << SubRegIndices.size() << ");\n\n";
+ << SubRegIndices.size() << ",\n";
else
- OS << "NULL, 0);\n\n";
+ OS << "NULL, 0,\n";
+
+ OS << " " << TargetName << "RegEncodingTable);\n\n";
EmitRegMapping(OS, Regs, true);