aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/PowerPC/PPCRegisterInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/PowerPC/PPCRegisterInfo.cpp')
-rw-r--r--lib/Target/PowerPC/PPCRegisterInfo.cpp223
1 files changed, 205 insertions, 18 deletions
diff --git a/lib/Target/PowerPC/PPCRegisterInfo.cpp b/lib/Target/PowerPC/PPCRegisterInfo.cpp
index cb315062ab..fd052792ea 100644
--- a/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -175,14 +175,12 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
};
static const unsigned ELF32_CalleeSavedRegs[] = {
- PPC::R13, PPC::R14, PPC::R15,
+ PPC::R14, PPC::R15,
PPC::R16, PPC::R17, PPC::R18, PPC::R19,
PPC::R20, PPC::R21, PPC::R22, PPC::R23,
PPC::R24, PPC::R25, PPC::R26, PPC::R27,
PPC::R28, PPC::R29, PPC::R30, PPC::R31,
- PPC::F9,
- PPC::F10, PPC::F11, PPC::F12, PPC::F13,
PPC::F14, PPC::F15, PPC::F16, PPC::F17,
PPC::F18, PPC::F19, PPC::F20, PPC::F21,
PPC::F22, PPC::F23, PPC::F24, PPC::F25,
@@ -190,6 +188,9 @@ PPCRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
PPC::F30, PPC::F31,
PPC::CR2, PPC::CR3, PPC::CR4,
+
+ PPC::VRSAVE,
+
PPC::V20, PPC::V21, PPC::V22, PPC::V23,
PPC::V24, PPC::V25, PPC::V26, PPC::V27,
PPC::V28, PPC::V29, PPC::V30, PPC::V31,
@@ -267,14 +268,12 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
};
static const TargetRegisterClass * const ELF32_CalleeSavedRegClasses[] = {
- &PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
+ &PPC::GPRCRegClass,&PPC::GPRCRegClass,
&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,&PPC::GPRCRegClass,
- &PPC::F8RCRegClass,
- &PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,&PPC::F8RCRegClass,
@@ -283,6 +282,8 @@ PPCRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
&PPC::CRRCRegClass,&PPC::CRRCRegClass,&PPC::CRRCRegClass,
+ &PPC::VRSAVERCRegClass,
+
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
@@ -358,10 +359,12 @@ BitVector PPCRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
Reserved.set(PPC::LR8);
Reserved.set(PPC::RM);
- // In Linux, r2 is reserved for the OS.
- if (!Subtarget.isDarwin())
- Reserved.set(PPC::R2);
-
+ // The SVR4 ABI reserves r2 and r13
+ if (Subtarget.isELF32_ABI()) {
+ Reserved.set(PPC::R2); // System-reserved register
+ Reserved.set(PPC::R13); // Small Data Area pointer register
+ }
+
// On PPC64, r13 is the thread pointer. Never allocate this register. Note
// that this is over conservative, as it also prevents allocation of R31 when
// the FP is not needed.
@@ -909,6 +912,7 @@ void PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const {
// don't have a frame pointer, calls, or dynamic alloca then we do not need
// to adjust the stack pointer (we fit in the Red Zone).
bool DisableRedZone = MF.getFunction()->hasFnAttr(Attribute::NoRedZone);
+ // FIXME SVR4 The SVR4 ABI has no red zone.
if (!DisableRedZone &&
FrameSize <= 224 && // Fits in red zone.
!MFI->hasVarSizedObjects() && // No dynamic alloca.
@@ -963,8 +967,7 @@ PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
MachineFrameInfo *MFI = MF.getFrameInfo();
// If the frame pointer save index hasn't been defined yet.
- if (!FPSI && (NoFramePointerElim || MFI->hasVarSizedObjects()) &&
- IsELF32_ABI) {
+ if (!FPSI && needsFP(MF) && IsELF32_ABI) {
// Find out what the fix offset of the frame pointer save area.
int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64,
IsMachoABI);
@@ -976,11 +979,10 @@ PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
// Reserve stack space to move the linkage area to in case of a tail call.
int TCSPDelta = 0;
- if (PerformTailCallOpt && (TCSPDelta=FI->getTailCallSPDelta()) < 0) {
- int AddFPOffsetAmount = IsELF32_ABI ? -4 : 0;
- MF.getFrameInfo()->CreateFixedObject( -1 * TCSPDelta,
- AddFPOffsetAmount + TCSPDelta);
+ if (PerformTailCallOpt && (TCSPDelta = FI->getTailCallSPDelta()) < 0) {
+ MF.getFrameInfo()->CreateFixedObject(-1 * TCSPDelta, TCSPDelta);
}
+
// Reserve a slot closest to SP or frame pointer if we have a dynalloc or
// a large stack, which will require scavenging a register to materialize a
// large offset.
@@ -999,6 +1001,169 @@ PPCRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
}
void
+PPCRegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
+ const {
+ // Early exit if not using the SVR4 ABI.
+ if (!Subtarget.isELF32_ABI()) {
+ return;
+ }
+
+ // Get callee saved register information.
+ MachineFrameInfo *FFI = MF.getFrameInfo();
+ const std::vector<CalleeSavedInfo> &CSI = FFI->getCalleeSavedInfo();
+
+ // Early exit if no callee saved registers are modified!
+ if (CSI.empty() && !needsFP(MF)) {
+ return;
+ }
+
+ unsigned MinGPR = PPC::R31;
+ unsigned MinFPR = PPC::F31;
+ unsigned MinVR = PPC::V31;
+
+ bool HasGPSaveArea = false;
+ bool HasFPSaveArea = false;
+ bool HasCRSaveArea = false;
+ bool HasVRSAVESaveArea = false;
+ bool HasVRSaveArea = false;
+
+ SmallVector<CalleeSavedInfo, 18> GPRegs;
+ SmallVector<CalleeSavedInfo, 18> FPRegs;
+ SmallVector<CalleeSavedInfo, 18> VRegs;
+
+ for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+ unsigned Reg = CSI[i].getReg();
+ const TargetRegisterClass *RC = CSI[i].getRegClass();
+
+ if (RC == PPC::GPRCRegisterClass) {
+ HasGPSaveArea = true;
+
+ GPRegs.push_back(CSI[i]);
+
+ if (Reg < MinGPR) {
+ MinGPR = Reg;
+ }
+ } else if (RC == PPC::F8RCRegisterClass) {
+ HasFPSaveArea = true;
+
+ FPRegs.push_back(CSI[i]);
+
+ if (Reg < MinFPR) {
+ MinFPR = Reg;
+ }
+ } else if ( RC == PPC::CRBITRCRegisterClass
+ || RC == PPC::CRRCRegisterClass) {
+ HasCRSaveArea = true;
+ } else if (RC == PPC::VRSAVERCRegisterClass) {
+ HasVRSAVESaveArea = true;
+ } else if (RC == PPC::VRRCRegisterClass) {
+ HasVRSaveArea = true;
+
+ VRegs.push_back(CSI[i]);
+
+ if (Reg < MinVR) {
+ MinVR = Reg;
+ }
+ } else {
+ assert(0 && "Unknown RegisterClass!");
+ }
+ }
+
+ PPCFunctionInfo *PFI = MF.getInfo<PPCFunctionInfo>();
+
+ int64_t LowerBound = 0;
+
+ // Take into account stack space reserved for tail calls.
+ int TCSPDelta = 0;
+ if (PerformTailCallOpt && (TCSPDelta = PFI->getTailCallSPDelta()) < 0) {
+ LowerBound = TCSPDelta;
+ }
+
+ // The Floating-point register save area is right below the back chain word
+ // of the previous stack frame.
+ if (HasFPSaveArea) {
+ for (unsigned i = 0, e = FPRegs.size(); i != e; ++i) {
+ int FI = FPRegs[i].getFrameIdx();
+
+ FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
+ }
+
+ LowerBound -= (31 - getRegisterNumbering(MinFPR) + 1) * 8;
+ }
+
+ // Check whether the frame pointer register is allocated. If so, make sure it
+ // is spilled to the correct offset.
+ if (needsFP(MF)) {
+ HasGPSaveArea = true;
+
+ int FI = PFI->getFramePointerSaveIndex();
+ assert(FI && "No Frame Pointer Save Slot!");
+
+ FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
+ }
+
+ // General register save area starts right below the Floating-point
+ // register save area.
+ if (HasGPSaveArea) {
+ // Move general register save area spill slots down, taking into account
+ // the size of the Floating-point register save area.
+ for (unsigned i = 0, e = GPRegs.size(); i != e; ++i) {
+ int FI = GPRegs[i].getFrameIdx();
+
+ FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
+ }
+
+ LowerBound -= (31 - getRegisterNumbering(MinGPR) + 1) * 4;
+ }
+
+ // The CR save area is below the general register save area.
+ if (HasCRSaveArea) {
+ // FIXME SVR4: Is it actually possible to have multiple elements in CSI
+ // which have the CR/CRBIT register class?
+ // Adjust the frame index of the CR spill slot.
+ for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+ const TargetRegisterClass *RC = CSI[i].getRegClass();
+
+ if (RC == PPC::CRBITRCRegisterClass || RC == PPC::CRRCRegisterClass) {
+ int FI = CSI[i].getFrameIdx();
+
+ FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
+ }
+ }
+
+ LowerBound -= 4; // The CR save area is always 4 bytes long.
+ }
+
+ if (HasVRSAVESaveArea) {
+ // FIXME SVR4: Is it actually possible to have multiple elements in CSI
+ // which have the VRSAVE register class?
+ // Adjust the frame index of the VRSAVE spill slot.
+ for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
+ const TargetRegisterClass *RC = CSI[i].getRegClass();
+
+ if (RC == PPC::VRSAVERCRegisterClass) {
+ int FI = CSI[i].getFrameIdx();
+
+ FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
+ }
+ }
+
+ LowerBound -= 4; // The VRSAVE save area is always 4 bytes long.
+ }
+
+ if (HasVRSaveArea) {
+ // Insert alignment padding, we need 16-byte alignment.
+ LowerBound = (LowerBound - 15) & ~(15);
+
+ for (unsigned i = 0, e = VRegs.size(); i != e; ++i) {
+ int FI = VRegs[i].getFrameIdx();
+
+ FFI->setObjectOffset(FI, LowerBound + FFI->getObjectOffset(FI));
+ }
+ }
+}
+
+void
PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
MachineBasicBlock::iterator MBBI = MBB.begin();
@@ -1041,7 +1206,18 @@ PPCRegisterInfo::emitPrologue(MachineFunction &MF) const {
bool HasFP = hasFP(MF) && FrameSize;
int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI);
- int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
+
+ int FPOffset = 0;
+ if (HasFP) {
+ if (Subtarget.isELF32_ABI()) {
+ MachineFrameInfo *FFI = MF.getFrameInfo();
+ int FPIndex = FI->getFramePointerSaveIndex();
+ assert(FPIndex && "No Frame Pointer Save Slot!");
+ FPOffset = FFI->getObjectOffset(FPIndex);
+ } else {
+ FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
+ }
+ }
if (IsPPC64) {
if (MustSaveLR)
@@ -1250,7 +1426,18 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
bool HasFP = hasFP(MF) && FrameSize;
int LROffset = PPCFrameInfo::getReturnSaveOffset(IsPPC64, IsMachoABI);
- int FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
+
+ int FPOffset = 0;
+ if (HasFP) {
+ if (Subtarget.isELF32_ABI()) {
+ MachineFrameInfo *FFI = MF.getFrameInfo();
+ int FPIndex = FI->getFramePointerSaveIndex();
+ assert(FPIndex && "No Frame Pointer Save Slot!");
+ FPOffset = FFI->getObjectOffset(FPIndex);
+ } else {
+ FPOffset = PPCFrameInfo::getFramePointerSaveOffset(IsPPC64, IsMachoABI);
+ }
+ }
bool UsesTCRet = RetOpcode == PPC::TCRETURNri ||
RetOpcode == PPC::TCRETURNdi ||