Add an OtherPreserved field to the CalleeSaved TableGen class.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 23 Aug 2013 02:25:47 +0000 (02:25 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 23 Aug 2013 02:25:47 +0000 (02:25 +0000)
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

include/llvm/Target/TargetCallingConv.td
lib/Target/Sparc/SparcCallingConv.td
lib/Target/Sparc/SparcRegisterInfo.cpp
lib/Target/Sparc/SparcRegisterInfo.h
utils/TableGen/RegisterInfoEmitter.cpp

index a53ed29f1ec159c0f4b9d72b327e1f257f70e138..c1bef28652e9a4f76bf1413968cf6bfe99092453 100644 (file)
@@ -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;
 }
index a181bcf3d2636951a1a9e2fbd25113ad731145bd..181165d6ddd47a7415c69d50e18ac6023de2b760 100644 (file)
@@ -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));
+}
index dc97f06b7ca02132ae23c24b813c1a2436ab13bc..0b0fe2d4fe8392a5e7ea92782a1bfe69881e365a 100644 (file)
@@ -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 {
index 6b77d4efa21cfac2a2c320ee8072690adf734531..ae056cdcf298069f4e030c83fd0c383be8c73e6a 100644 (file)
@@ -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;
 
index 731dccf75e879e52409210aa44a00bf46186c961..9a30e159be4b0f78be0b8a2676afeec05bdcf301 100644 (file)
@@ -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";