summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-03-24 19:18:48 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2016-03-24 19:18:48 +0000
commit181fdbd174861a9001ec481a500221ea0f6a6b40 (patch)
treee12081c17901d7ec6cc3cb17282b9e1e4b2de77e /llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
parent6642bb3337457b3c692b1aca56d3c8ee0c46c7a4 (diff)
downloadbcm5719-llvm-181fdbd174861a9001ec481a500221ea0f6a6b40.tar.gz
bcm5719-llvm-181fdbd174861a9001ec481a500221ea0f6a6b40.zip
[Hexagon] Generate PIC-specific versions of save/restore routines
In PIC mode, the registers R14, R15 and R28 are reserved for use by the PLT handling code. This causes all functions to clobber these registers. While this is not new for regular function calls, it does also apply to save/restore functions, which do not follow the standard ABI conventions with respect to the volatile/non-volatile registers. Patch by Jyotsna Verma. llvm-svn: 264324
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp22
1 files changed, 17 insertions, 5 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
index d90592df074..6ad82e8c21f 100644
--- a/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp
@@ -536,7 +536,8 @@ void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const {
// Check for RESTORE_DEALLOC_RET* tail call. Don't emit an extra dealloc-
// frame instruction if we encounter it.
- if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4) {
+ if (RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4 ||
+ RetOpc == Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC) {
MachineBasicBlock::iterator It = RetI;
++It;
// Delete all instructions after the RESTORE (except labels).
@@ -556,7 +557,8 @@ void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const {
if (!MBB.empty() && InsertPt != MBB.begin()) {
MachineBasicBlock::iterator PrevIt = std::prev(InsertPt);
unsigned COpc = PrevIt->getOpcode();
- if (COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4)
+ if (COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4 ||
+ COpc == Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC)
NeedsDeallocframe = false;
}
@@ -922,10 +924,16 @@ bool HexagonFrameLowering::insertCSRSpillsInBlock(MachineBasicBlock &MBB,
if (useSpillFunction(MF, CSI)) {
unsigned MaxReg = getMaxCalleeSavedReg(CSI, HRI);
const char *SpillFun = getSpillFunctionFor(MaxReg, SK_ToMem);
+ auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
+ bool IsPIC = HTM.getRelocationModel() == Reloc::PIC_;
+
// Call spill function.
DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc() : DebugLoc();
+ unsigned SpillOpc = IsPIC ? Hexagon::SAVE_REGISTERS_CALL_V4_PIC
+ : Hexagon::SAVE_REGISTERS_CALL_V4;
+
MachineInstr *SaveRegsCall =
- BuildMI(MBB, MI, DL, HII.get(Hexagon::SAVE_REGISTERS_CALL_V4))
+ BuildMI(MBB, MI, DL, HII.get(SpillOpc))
.addExternalSymbol(SpillFun);
// Add callee-saved registers as use.
addCalleeSaveRegistersAsImpOperand(SaveRegsCall, MaxReg, false);
@@ -965,6 +973,8 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
unsigned MaxR = getMaxCalleeSavedReg(CSI, HRI);
SpillKind Kind = HasTC ? SK_FromMemTailcall : SK_FromMem;
const char *RestoreFn = getSpillFunctionFor(MaxR, Kind);
+ auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
+ bool IsPIC = HTM.getRelocationModel() == Reloc::PIC_;
// Call spill function.
DebugLoc DL = MI != MBB.end() ? MI->getDebugLoc()
@@ -972,14 +982,16 @@ bool HexagonFrameLowering::insertCSRRestoresInBlock(MachineBasicBlock &MBB,
MachineInstr *DeallocCall = nullptr;
if (HasTC) {
- unsigned ROpc = Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
+ unsigned ROpc = IsPIC ? Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4_PIC
+ : Hexagon::RESTORE_DEALLOC_BEFORE_TAILCALL_V4;
DeallocCall = BuildMI(MBB, MI, DL, HII.get(ROpc))
.addExternalSymbol(RestoreFn);
} else {
// The block has a return.
MachineBasicBlock::iterator It = MBB.getFirstTerminator();
assert(It->isReturn() && std::next(It) == MBB.end());
- unsigned ROpc = Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
+ unsigned ROpc = IsPIC ? Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC
+ : Hexagon::RESTORE_DEALLOC_RET_JMP_V4;
DeallocCall = BuildMI(MBB, It, DL, HII.get(ROpc))
.addExternalSymbol(RestoreFn);
// Transfer the function live-out registers.
OpenPOWER on IntegriCloud