diff options
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 7 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMCallingConv.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMSubtarget.h | 7 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/Thumb1FrameLowering.cpp | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/macho-frame-offset.ll | 12 |
6 files changed, 41 insertions, 11 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index a93da9e98da..a873b2b26a4 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -60,8 +60,11 @@ static unsigned getFramePointerReg(const ARMSubtarget &STI) { const MCPhysReg* ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { const ARMSubtarget &STI = MF->getSubtarget<ARMSubtarget>(); + bool UseSplitPush = STI.splitFramePushPop(); const MCPhysReg *RegList = - STI.isTargetDarwin() ? CSR_iOS_SaveList : CSR_AAPCS_SaveList; + STI.isTargetDarwin() + ? CSR_iOS_SaveList + : (UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList); const Function *F = MF->getFunction(); if (F->getCallingConv() == CallingConv::GHC) { @@ -72,7 +75,7 @@ ARMBaseRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { if (STI.isMClass()) { // M-class CPUs have hardware which saves the registers needed to allow a // function conforming to the AAPCS to function as a handler. - return CSR_AAPCS_SaveList; + return UseSplitPush ? CSR_AAPCS_SplitPush_SaveList : CSR_AAPCS_SaveList; } else if (F->getFnAttribute("interrupt").getValueAsString() == "FIQ") { // Fast interrupt mode gives the handler a private copy of R8-R14, so less // need to be saved to restore user-mode state. diff --git a/llvm/lib/Target/ARM/ARMCallingConv.td b/llvm/lib/Target/ARM/ARMCallingConv.td index c477208b111..edb69581b9d 100644 --- a/llvm/lib/Target/ARM/ARMCallingConv.td +++ b/llvm/lib/Target/ARM/ARMCallingConv.td @@ -246,6 +246,14 @@ def CSR_NoRegs : CalleeSavedRegs<(add)>; def CSR_AAPCS : CalleeSavedRegs<(add LR, R11, R10, R9, R8, R7, R6, R5, R4, (sequence "D%u", 15, 8))>; +// The order of callee-saved registers needs to match the order we actually push +// them in FrameLowering, because this order is what's used by +// PrologEpilogInserter to allocate frame index slots. So when R7 is the frame +// pointer, we use this AAPCS alternative. +def CSR_AAPCS_SplitPush : CalleeSavedRegs<(add LR, R7, R6, R5, R4, + R11, R10, R9, R8, + (sequence "D%u", 15, 8))>; + // Constructors and destructors return 'this' in the ARM C++ ABI; since 'this' // and the pointer return value are both passed in R0 in these cases, this can // be partially modelled by treating R0 as a callee-saved register diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp index c5e0b82f7fd..e2fe8b968a7 100644 --- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -355,7 +355,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, case ARM::R10: case ARM::R11: case ARM::R12: - if (STI.isTargetMachO()) { + if (STI.splitFramePushPop()) { GPRCS2Size += 4; break; } @@ -559,7 +559,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, case ARM::R10: case ARM::R11: case ARM::R12: - if (STI.isTargetMachO()) + if (STI.splitFramePushPop()) break; // fallthrough case ARM::R0: @@ -592,7 +592,7 @@ void ARMFrameLowering::emitPrologue(MachineFunction &MF, case ARM::R10: case ARM::R11: case ARM::R12: - if (STI.isTargetMachO()) { + if (STI.splitFramePushPop()) { unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); unsigned Offset = MFI->getObjectOffset(FI); unsigned CFIIndex = MMI.addFrameInst( @@ -904,7 +904,7 @@ void ARMFrameLowering::emitPushInst(MachineBasicBlock &MBB, unsigned LastReg = 0; for (; i != 0; --i) { unsigned Reg = CSI[i-1].getReg(); - if (!(Func)(Reg, STI.isTargetMachO())) continue; + if (!(Func)(Reg, STI.splitFramePushPop())) continue; // D-registers in the aligned area DPRCS2 are NOT spilled here. if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs) @@ -985,7 +985,7 @@ void ARMFrameLowering::emitPopInst(MachineBasicBlock &MBB, bool DeleteRet = false; for (; i != 0; --i) { unsigned Reg = CSI[i-1].getReg(); - if (!(Func)(Reg, STI.isTargetMachO())) continue; + if (!(Func)(Reg, STI.splitFramePushPop())) continue; // The aligned reloads from area DPRCS2 are not inserted here. if (Reg >= ARM::D8 && Reg < ARM::D8 + NumAlignedDPRCS2Regs) @@ -1549,7 +1549,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, if (Spilled) { NumGPRSpills++; - if (!STI.isTargetMachO()) { + if (!STI.splitFramePushPop()) { if (Reg == ARM::LR) LRSpilled = true; CS1Spilled = true; @@ -1571,7 +1571,7 @@ void ARMFrameLowering::determineCalleeSaves(MachineFunction &MF, break; } } else { - if (!STI.isTargetMachO()) { + if (!STI.splitFramePushPop()) { UnspilledCS1GPRs.push_back(Reg); continue; } diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index ec1212d37b3..7c9ea7d9253 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -455,6 +455,13 @@ public: return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9; } + /// Returns true if the frame setup is split into two separate pushes (first + /// r0-r7,lr then r8-r11), principally so that the frame pointer is adjacent + /// to lr. + bool splitFramePushPop() const { + return isTargetMachO(); + } + bool useStride4VFPs(const MachineFunction &MF) const; bool useMovt(const MachineFunction &MF) const; diff --git a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp index 31828a32fd3..a6ec37e6469 100644 --- a/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp +++ b/llvm/lib/Target/ARM/Thumb1FrameLowering.cpp @@ -151,7 +151,7 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF, case ARM::R9: case ARM::R10: case ARM::R11: - if (STI.isTargetMachO()) { + if (STI.splitFramePushPop()) { GPRCS2Size += 4; break; } @@ -213,7 +213,7 @@ void Thumb1FrameLowering::emitPrologue(MachineFunction &MF, case ARM::R10: case ARM::R11: case ARM::R12: - if (STI.isTargetMachO()) + if (STI.splitFramePushPop()) break; // fallthough case ARM::R0: diff --git a/llvm/test/CodeGen/ARM/macho-frame-offset.ll b/llvm/test/CodeGen/ARM/macho-frame-offset.ll new file mode 100644 index 00000000000..f3dacf66b6c --- /dev/null +++ b/llvm/test/CodeGen/ARM/macho-frame-offset.ll @@ -0,0 +1,12 @@ +; RUN: llc -mtriple thumbv7m-apple-macho -disable-fp-elim -o - %s | FileCheck %s + +define void @func() { +; CHECK-LABEL: func: +; CHECK: push {r6, r7, lr} +; CHECK: add r7, sp, #4 + call void @bar() + call void asm sideeffect "", "~{r11}"() + ret void +} + +declare void @bar() |