diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-03-24 19:18:48 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2016-03-24 19:18:48 +0000 |
commit | 181fdbd174861a9001ec481a500221ea0f6a6b40 (patch) | |
tree | e12081c17901d7ec6cc3cb17282b9e1e4b2de77e /llvm/lib/Target/Hexagon/HexagonFrameLowering.cpp | |
parent | 6642bb3337457b3c692b1aca56d3c8ee0c46c7a4 (diff) | |
download | bcm5719-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.cpp | 22 |
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. |