aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2013-08-23 02:25:47 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2013-08-23 02:25:47 +0000
commitd93969c32a6bbae3326a1f485c4c85be1cb39406 (patch)
treef54d593d4fe2d4b2149858fa7607f4285ff053e9
parent0a248bf714f18b1cdcda5d7b811303c232d6e885 (diff)
downloadexternal_llvm-d93969c32a6bbae3326a1f485c4c85be1cb39406.zip
external_llvm-d93969c32a6bbae3326a1f485c4c85be1cb39406.tar.gz
external_llvm-d93969c32a6bbae3326a1f485c4c85be1cb39406.tar.bz2
Add an OtherPreserved field to the CalleeSaved TableGen class.
This field specifies registers that are preserved across function calls, but that should not be included in the generates SaveList array. This can be used ot generate regmasks for architectures that save registers through other means, like SPARC's register windows. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189084 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetCallingConv.td6
-rw-r--r--lib/Target/Sparc/SparcCallingConv.td6
-rw-r--r--lib/Target/Sparc/SparcRegisterInfo.cpp8
-rw-r--r--lib/Target/Sparc/SparcRegisterInfo.h1
-rw-r--r--utils/TableGen/RegisterInfoEmitter.cpp14
5 files changed, 32 insertions, 3 deletions
diff --git a/include/llvm/Target/TargetCallingConv.td b/include/llvm/Target/TargetCallingConv.td
index a53ed29..c1bef28 100644
--- a/include/llvm/Target/TargetCallingConv.td
+++ b/include/llvm/Target/TargetCallingConv.td
@@ -143,4 +143,10 @@ class CallingConv<list<CCAction> actions> {
/// returning from getCallPreservedMask().
class CalleeSavedRegs<dag saves> {
dag SaveList = saves;
+
+ // Registers that are also preserved across function calls, but should not be
+ // included in the generated FOO_SaveList array. These registers will be
+ // included in the FOO_RegMask bit mask. This can be used for registers that
+ // are saved automatically, like the SPARC register windows.
+ dag OtherPreserved;
}
diff --git a/lib/Target/Sparc/SparcCallingConv.td b/lib/Target/Sparc/SparcCallingConv.td
index a181bcf..181165d 100644
--- a/lib/Target/Sparc/SparcCallingConv.td
+++ b/lib/Target/Sparc/SparcCallingConv.td
@@ -117,3 +117,9 @@ def CC_Sparc64 : CallingConv<[
// arguments whether they are passed in registers or not.
CCCustom<"CC_Sparc64_Full">
]>;
+
+// Callee-saved registers are handled by the register window mechanism.
+def CSR : CalleeSavedRegs<(add)> {
+ let OtherPreserved = (add (sequence "I%u", 0, 7),
+ (sequence "L%u", 0, 7));
+}
diff --git a/lib/Target/Sparc/SparcRegisterInfo.cpp b/lib/Target/Sparc/SparcRegisterInfo.cpp
index dc97f06..0b0fe2d 100644
--- a/lib/Target/Sparc/SparcRegisterInfo.cpp
+++ b/lib/Target/Sparc/SparcRegisterInfo.cpp
@@ -40,8 +40,12 @@ SparcRegisterInfo::SparcRegisterInfo(SparcSubtarget &st)
const uint16_t* SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF)
const {
- static const uint16_t CalleeSavedRegs[] = { 0 };
- return CalleeSavedRegs;
+ return CSR_SaveList;
+}
+
+const uint32_t*
+SparcRegisterInfo::getCallPreservedMask(CallingConv::ID CC) const {
+ return CSR_RegMask;
}
BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
diff --git a/lib/Target/Sparc/SparcRegisterInfo.h b/lib/Target/Sparc/SparcRegisterInfo.h
index 6b77d4e..ae056cd 100644
--- a/lib/Target/Sparc/SparcRegisterInfo.h
+++ b/lib/Target/Sparc/SparcRegisterInfo.h
@@ -32,6 +32,7 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo {
/// Code Generation virtual methods...
const uint16_t *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
+ const uint32_t* getCallPreservedMask(CallingConv::ID CC) const;
BitVector getReservedRegs(const MachineFunction &MF) const;
diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp
index 731dccf..9a30e15 100644
--- a/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1314,9 +1314,21 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
OS << "0 };\n";
// Emit the *_RegMask bit mask of call-preserved registers.
+ BitVector Covered = RegBank.computeCoveredRegisters(*Regs);
+
+ // Check for an optional OtherPreserved set.
+ // Add those registers to RegMask, but not to SaveList.
+ if (DagInit *OPDag =
+ dyn_cast<DagInit>(CSRSet->getValueInit("OtherPreserved"))) {
+ SetTheory::RecSet OPSet;
+ RegBank.getSets().evaluate(OPDag, OPSet, CSRSet->getLoc());
+ Covered |= RegBank.computeCoveredRegisters(
+ ArrayRef<Record*>(OPSet.begin(), OPSet.end()));
+ }
+
OS << "static const uint32_t " << CSRSet->getName()
<< "_RegMask[] = { ";
- printBitVectorAsHex(OS, RegBank.computeCoveredRegisters(*Regs), 32);
+ printBitVectorAsHex(OS, Covered, 32);
OS << "};\n";
}
OS << "\n\n";