diff options
Diffstat (limited to 'lib/Target/SystemZ/SystemZFrameInfo.cpp')
-rw-r--r-- | lib/Target/SystemZ/SystemZFrameInfo.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/lib/Target/SystemZ/SystemZFrameInfo.cpp b/lib/Target/SystemZ/SystemZFrameInfo.cpp index 7fde9a0..d453940 100644 --- a/lib/Target/SystemZ/SystemZFrameInfo.cpp +++ b/lib/Target/SystemZ/SystemZFrameInfo.cpp @@ -351,3 +351,38 @@ SystemZFrameInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, return true; } + +void +SystemZFrameInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, + RegScavenger *RS) const { + // Determine whether R15/R14 will ever be clobbered inside the function. And + // if yes - mark it as 'callee' saved. + MachineFrameInfo *FFI = MF.getFrameInfo(); + MachineRegisterInfo &MRI = MF.getRegInfo(); + + // Check whether high FPRs are ever used, if yes - we need to save R15 as + // well. + static const unsigned HighFPRs[] = { + SystemZ::F8L, SystemZ::F9L, SystemZ::F10L, SystemZ::F11L, + SystemZ::F12L, SystemZ::F13L, SystemZ::F14L, SystemZ::F15L, + SystemZ::F8S, SystemZ::F9S, SystemZ::F10S, SystemZ::F11S, + SystemZ::F12S, SystemZ::F13S, SystemZ::F14S, SystemZ::F15S, + }; + + bool HighFPRsUsed = false; + for (unsigned i = 0, e = array_lengthof(HighFPRs); i != e; ++i) + HighFPRsUsed |= MRI.isPhysRegUsed(HighFPRs[i]); + + if (FFI->hasCalls()) + /* FIXME: function is varargs */ + /* FIXME: function grabs RA */ + /* FIXME: function calls eh_return */ + MRI.setPhysRegUsed(SystemZ::R14D); + + if (HighFPRsUsed || + FFI->hasCalls() || + FFI->getObjectIndexEnd() != 0 || // Contains automatic variables + FFI->hasVarSizedObjects() // Function calls dynamic alloca's + /* FIXME: function is varargs */) + MRI.setPhysRegUsed(SystemZ::R15D); +} |