172062f5744557e270a38192554c3126ea5f97434Tim Northover//===- AArch64FrameLowering.cpp - AArch64 Frame Information ---------------===// 272062f5744557e270a38192554c3126ea5f97434Tim Northover// 372062f5744557e270a38192554c3126ea5f97434Tim Northover// The LLVM Compiler Infrastructure 472062f5744557e270a38192554c3126ea5f97434Tim Northover// 572062f5744557e270a38192554c3126ea5f97434Tim Northover// This file is distributed under the University of Illinois Open Source 672062f5744557e270a38192554c3126ea5f97434Tim Northover// License. See LICENSE.TXT for details. 772062f5744557e270a38192554c3126ea5f97434Tim Northover// 872062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===// 972062f5744557e270a38192554c3126ea5f97434Tim Northover// 1072062f5744557e270a38192554c3126ea5f97434Tim Northover// This file contains the AArch64 implementation of TargetFrameLowering class. 1172062f5744557e270a38192554c3126ea5f97434Tim Northover// 1272062f5744557e270a38192554c3126ea5f97434Tim Northover//===----------------------------------------------------------------------===// 1372062f5744557e270a38192554c3126ea5f97434Tim Northover 1472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64.h" 1572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64FrameLowering.h" 1672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64MachineFunctionInfo.h" 1772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "AArch64InstrInfo.h" 1872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineFrameInfo.h" 1972062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineFunction.h" 2072062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineInstrBuilder.h" 2172062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineMemOperand.h" 2272062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineModuleInfo.h" 2372062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/MachineRegisterInfo.h" 2472062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/CodeGen/RegisterScavenging.h" 2572062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/IR/Function.h" 2672062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/MC/MachineLocation.h" 2772062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/Debug.h" 2872062f5744557e270a38192554c3126ea5f97434Tim Northover#include "llvm/Support/ErrorHandling.h" 2972062f5744557e270a38192554c3126ea5f97434Tim Northover 3072062f5744557e270a38192554c3126ea5f97434Tim Northoverusing namespace llvm; 3172062f5744557e270a38192554c3126ea5f97434Tim Northover 3272062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64FrameLowering::splitSPAdjustments(uint64_t Total, 3372062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t &Initial, 3472062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t &Residual) const { 3572062f5744557e270a38192554c3126ea5f97434Tim Northover // 0x1f0 here is a pessimistic (i.e. realistic) boundary: x-register LDP 3672062f5744557e270a38192554c3126ea5f97434Tim Northover // instructions have a 7-bit signed immediate scaled by 8, giving a reach of 3772062f5744557e270a38192554c3126ea5f97434Tim Northover // 0x1f8, but stack adjustment should always be a multiple of 16. 3872062f5744557e270a38192554c3126ea5f97434Tim Northover if (Total <= 0x1f0) { 3972062f5744557e270a38192554c3126ea5f97434Tim Northover Initial = Total; 4072062f5744557e270a38192554c3126ea5f97434Tim Northover Residual = 0; 4172062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 4272062f5744557e270a38192554c3126ea5f97434Tim Northover Initial = 0x1f0; 4372062f5744557e270a38192554c3126ea5f97434Tim Northover Residual = Total - Initial; 4472062f5744557e270a38192554c3126ea5f97434Tim Northover } 4572062f5744557e270a38192554c3126ea5f97434Tim Northover} 4672062f5744557e270a38192554c3126ea5f97434Tim Northover 4772062f5744557e270a38192554c3126ea5f97434Tim Northovervoid AArch64FrameLowering::emitPrologue(MachineFunction &MF) const { 4872062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64MachineFunctionInfo *FuncInfo = 4972062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getInfo<AArch64MachineFunctionInfo>(); 5072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock &MBB = MF.front(); 5172062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI = MBB.begin(); 5272062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo *MFI = MF.getFrameInfo(); 5372062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 5472062f5744557e270a38192554c3126ea5f97434Tim Northover DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 5572062f5744557e270a38192554c3126ea5f97434Tim Northover 5672062f5744557e270a38192554c3126ea5f97434Tim Northover MachineModuleInfo &MMI = MF.getMMI(); 5799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = MMI.getContext().getRegisterInfo(); 5872062f5744557e270a38192554c3126ea5f97434Tim Northover bool NeedsFrameMoves = MMI.hasDebugInfo() 5972062f5744557e270a38192554c3126ea5f97434Tim Northover || MF.getFunction()->needsUnwindTableEntry(); 6072062f5744557e270a38192554c3126ea5f97434Tim Northover 6172062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t NumInitialBytes, NumResidualBytes; 6272062f5744557e270a38192554c3126ea5f97434Tim Northover 6372062f5744557e270a38192554c3126ea5f97434Tim Northover // Currently we expect the stack to be laid out by 6472062f5744557e270a38192554c3126ea5f97434Tim Northover // sub sp, sp, #initial 6572062f5744557e270a38192554c3126ea5f97434Tim Northover // stp x29, x30, [sp, #offset] 6672062f5744557e270a38192554c3126ea5f97434Tim Northover // ... 6772062f5744557e270a38192554c3126ea5f97434Tim Northover // str xxx, [sp, #offset] 6872062f5744557e270a38192554c3126ea5f97434Tim Northover // sub sp, sp, #rest (possibly via extra instructions). 6972062f5744557e270a38192554c3126ea5f97434Tim Northover if (MFI->getCalleeSavedInfo().size()) { 7072062f5744557e270a38192554c3126ea5f97434Tim Northover // If there are callee-saved registers, we want to store them efficiently as 7172062f5744557e270a38192554c3126ea5f97434Tim Northover // a block, and virtual base assignment happens too early to do it for us so 7272062f5744557e270a38192554c3126ea5f97434Tim Northover // we adjust the stack in two phases: first just for callee-saved fiddling, 7372062f5744557e270a38192554c3126ea5f97434Tim Northover // then to allocate the rest of the frame. 7472062f5744557e270a38192554c3126ea5f97434Tim Northover splitSPAdjustments(MFI->getStackSize(), NumInitialBytes, NumResidualBytes); 7572062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 7672062f5744557e270a38192554c3126ea5f97434Tim Northover // If there aren't any callee-saved registers, two-phase adjustment is 7772062f5744557e270a38192554c3126ea5f97434Tim Northover // inefficient. It's more efficient to adjust with NumInitialBytes too 7872062f5744557e270a38192554c3126ea5f97434Tim Northover // because when we're in a "callee pops argument space" situation, that pop 7972062f5744557e270a38192554c3126ea5f97434Tim Northover // must be tacked onto Initial for correctness. 8072062f5744557e270a38192554c3126ea5f97434Tim Northover NumInitialBytes = MFI->getStackSize(); 8172062f5744557e270a38192554c3126ea5f97434Tim Northover NumResidualBytes = 0; 8272062f5744557e270a38192554c3126ea5f97434Tim Northover } 8372062f5744557e270a38192554c3126ea5f97434Tim Northover 8472062f5744557e270a38192554c3126ea5f97434Tim Northover // Tell everyone else how much adjustment we're expecting them to use. In 8572062f5744557e270a38192554c3126ea5f97434Tim Northover // particular if an adjustment is required for a tail call the epilogue could 8672062f5744557e270a38192554c3126ea5f97434Tim Northover // have a different view of things. 8772062f5744557e270a38192554c3126ea5f97434Tim Northover FuncInfo->setInitialStackAdjust(NumInitialBytes); 8872062f5744557e270a38192554c3126ea5f97434Tim Northover 8972062f5744557e270a38192554c3126ea5f97434Tim Northover emitSPUpdate(MBB, MBBI, DL, TII, AArch64::X16, -NumInitialBytes, 9072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr::FrameSetup); 9172062f5744557e270a38192554c3126ea5f97434Tim Northover 9272062f5744557e270a38192554c3126ea5f97434Tim Northover if (NeedsFrameMoves && NumInitialBytes) { 9372062f5744557e270a38192554c3126ea5f97434Tim Northover // We emit this update even if the CFA is set from a frame pointer later so 9472062f5744557e270a38192554c3126ea5f97434Tim Northover // that the CFA is valid in the interim. 9572062f5744557e270a38192554c3126ea5f97434Tim Northover MCSymbol *SPLabel = MMI.getContext().CreateTempSymbol(); 9672062f5744557e270a38192554c3126ea5f97434Tim Northover BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::PROLOG_LABEL)) 9772062f5744557e270a38192554c3126ea5f97434Tim Northover .addSym(SPLabel); 9872062f5744557e270a38192554c3126ea5f97434Tim Northover 9972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Dst(MachineLocation::VirtualFP); 10099cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Reg = MRI->getDwarfRegNum(AArch64::XSP, true); 1016b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst( 1026b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MCCFIInstruction::createDefCfa(SPLabel, Reg, -NumInitialBytes)); 10372062f5744557e270a38192554c3126ea5f97434Tim Northover } 10472062f5744557e270a38192554c3126ea5f97434Tim Northover 10572062f5744557e270a38192554c3126ea5f97434Tim Northover // Otherwise we need to set the frame pointer and/or add a second stack 10672062f5744557e270a38192554c3126ea5f97434Tim Northover // adjustment. 10772062f5744557e270a38192554c3126ea5f97434Tim Northover 10872062f5744557e270a38192554c3126ea5f97434Tim Northover bool FPNeedsSetting = hasFP(MF); 10972062f5744557e270a38192554c3126ea5f97434Tim Northover for (; MBBI != MBB.end(); ++MBBI) { 11072062f5744557e270a38192554c3126ea5f97434Tim Northover // Note that this search makes strong assumptions about the operation used 11172062f5744557e270a38192554c3126ea5f97434Tim Northover // to store the frame-pointer: it must be "STP x29, x30, ...". This could 11272062f5744557e270a38192554c3126ea5f97434Tim Northover // change in future, but until then there's no point in implementing 11372062f5744557e270a38192554c3126ea5f97434Tim Northover // untestable more generic cases. 11472062f5744557e270a38192554c3126ea5f97434Tim Northover if (FPNeedsSetting && MBBI->getOpcode() == AArch64::LSPair64_STR 11572062f5744557e270a38192554c3126ea5f97434Tim Northover && MBBI->getOperand(0).getReg() == AArch64::X29) { 11672062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t X29FrameIdx = MBBI->getOperand(2).getIndex(); 11772062f5744557e270a38192554c3126ea5f97434Tim Northover FuncInfo->setFramePointerOffset(MFI->getObjectOffset(X29FrameIdx)); 11872062f5744557e270a38192554c3126ea5f97434Tim Northover 11972062f5744557e270a38192554c3126ea5f97434Tim Northover ++MBBI; 12072062f5744557e270a38192554c3126ea5f97434Tim Northover emitRegUpdate(MBB, MBBI, DL, TII, AArch64::X29, AArch64::XSP, 12172062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64::X29, 12272062f5744557e270a38192554c3126ea5f97434Tim Northover NumInitialBytes + MFI->getObjectOffset(X29FrameIdx), 12372062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr::FrameSetup); 12472062f5744557e270a38192554c3126ea5f97434Tim Northover 12572062f5744557e270a38192554c3126ea5f97434Tim Northover // The offset adjustment used when emitting debugging locations relative 12672062f5744557e270a38192554c3126ea5f97434Tim Northover // to whatever frame base is set. AArch64 uses the default frame base (FP 12772062f5744557e270a38192554c3126ea5f97434Tim Northover // or SP) and this adjusts the calculations to be correct. 12872062f5744557e270a38192554c3126ea5f97434Tim Northover MFI->setOffsetAdjustment(- MFI->getObjectOffset(X29FrameIdx) 12972062f5744557e270a38192554c3126ea5f97434Tim Northover - MFI->getStackSize()); 13072062f5744557e270a38192554c3126ea5f97434Tim Northover 13172062f5744557e270a38192554c3126ea5f97434Tim Northover if (NeedsFrameMoves) { 13272062f5744557e270a38192554c3126ea5f97434Tim Northover MCSymbol *FPLabel = MMI.getContext().CreateTempSymbol(); 13372062f5744557e270a38192554c3126ea5f97434Tim Northover BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::PROLOG_LABEL)) 13472062f5744557e270a38192554c3126ea5f97434Tim Northover .addSym(FPLabel); 13599cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Reg = MRI->getDwarfRegNum(AArch64::X29, true); 1366b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned Offset = MFI->getObjectOffset(X29FrameIdx); 1376b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst(MCCFIInstruction::createDefCfa(FPLabel, Reg, Offset)); 13872062f5744557e270a38192554c3126ea5f97434Tim Northover } 13972062f5744557e270a38192554c3126ea5f97434Tim Northover 14072062f5744557e270a38192554c3126ea5f97434Tim Northover FPNeedsSetting = false; 14172062f5744557e270a38192554c3126ea5f97434Tim Northover } 14272062f5744557e270a38192554c3126ea5f97434Tim Northover 14372062f5744557e270a38192554c3126ea5f97434Tim Northover if (!MBBI->getFlag(MachineInstr::FrameSetup)) 14472062f5744557e270a38192554c3126ea5f97434Tim Northover break; 14572062f5744557e270a38192554c3126ea5f97434Tim Northover } 14672062f5744557e270a38192554c3126ea5f97434Tim Northover 14772062f5744557e270a38192554c3126ea5f97434Tim Northover assert(!FPNeedsSetting && "Frame pointer couldn't be set"); 14872062f5744557e270a38192554c3126ea5f97434Tim Northover 14972062f5744557e270a38192554c3126ea5f97434Tim Northover emitSPUpdate(MBB, MBBI, DL, TII, AArch64::X16, -NumResidualBytes, 15072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr::FrameSetup); 15172062f5744557e270a38192554c3126ea5f97434Tim Northover 15272062f5744557e270a38192554c3126ea5f97434Tim Northover // Now we emit the rest of the frame setup information, if necessary: we've 15372062f5744557e270a38192554c3126ea5f97434Tim Northover // already noted the FP and initial SP moves so we're left with the prologue's 15472062f5744557e270a38192554c3126ea5f97434Tim Northover // final SP update and callee-saved register locations. 15572062f5744557e270a38192554c3126ea5f97434Tim Northover if (!NeedsFrameMoves) 15672062f5744557e270a38192554c3126ea5f97434Tim Northover return; 15772062f5744557e270a38192554c3126ea5f97434Tim Northover 15872062f5744557e270a38192554c3126ea5f97434Tim Northover // Reuse the label if appropriate, so create it in this outer scope. 15972062f5744557e270a38192554c3126ea5f97434Tim Northover MCSymbol *CSLabel = 0; 16072062f5744557e270a38192554c3126ea5f97434Tim Northover 16172062f5744557e270a38192554c3126ea5f97434Tim Northover // The rest of the stack adjustment 16272062f5744557e270a38192554c3126ea5f97434Tim Northover if (!hasFP(MF) && NumResidualBytes) { 16372062f5744557e270a38192554c3126ea5f97434Tim Northover CSLabel = MMI.getContext().CreateTempSymbol(); 16472062f5744557e270a38192554c3126ea5f97434Tim Northover BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::PROLOG_LABEL)) 16572062f5744557e270a38192554c3126ea5f97434Tim Northover .addSym(CSLabel); 16672062f5744557e270a38192554c3126ea5f97434Tim Northover 16772062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Dst(MachineLocation::VirtualFP); 16899cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Reg = MRI->getDwarfRegNum(AArch64::XSP, true); 1696b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned Offset = NumResidualBytes + NumInitialBytes; 1706b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst(MCCFIInstruction::createDefCfa(CSLabel, Reg, -Offset)); 17172062f5744557e270a38192554c3126ea5f97434Tim Northover } 17272062f5744557e270a38192554c3126ea5f97434Tim Northover 17372062f5744557e270a38192554c3126ea5f97434Tim Northover // And any callee-saved registers (it's fine to leave them to the end here, 17472062f5744557e270a38192554c3126ea5f97434Tim Northover // because the old values are still valid at this point. 17572062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 17672062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.size()) { 17772062f5744557e270a38192554c3126ea5f97434Tim Northover if (!CSLabel) { 17872062f5744557e270a38192554c3126ea5f97434Tim Northover CSLabel = MMI.getContext().CreateTempSymbol(); 17972062f5744557e270a38192554c3126ea5f97434Tim Northover BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::PROLOG_LABEL)) 18072062f5744557e270a38192554c3126ea5f97434Tim Northover .addSym(CSLabel); 18172062f5744557e270a38192554c3126ea5f97434Tim Northover } 18272062f5744557e270a38192554c3126ea5f97434Tim Northover 18372062f5744557e270a38192554c3126ea5f97434Tim Northover for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 18472062f5744557e270a38192554c3126ea5f97434Tim Northover E = CSI.end(); I != E; ++I) { 1856b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola unsigned Offset = MFI->getObjectOffset(I->getFrameIdx()); 18699cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling unsigned Reg = MRI->getDwarfRegNum(I->getReg(), true); 1876b67ffd68bb2e555b1b512a809f3c82c68f3debeRafael Espindola MMI.addFrameInst(MCCFIInstruction::createOffset(CSLabel, Reg, Offset)); 18872062f5744557e270a38192554c3126ea5f97434Tim Northover } 18972062f5744557e270a38192554c3126ea5f97434Tim Northover } 19072062f5744557e270a38192554c3126ea5f97434Tim Northover} 19172062f5744557e270a38192554c3126ea5f97434Tim Northover 19272062f5744557e270a38192554c3126ea5f97434Tim Northovervoid 19372062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::emitEpilogue(MachineFunction &MF, 19472062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock &MBB) const { 19572062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64MachineFunctionInfo *FuncInfo = 19672062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getInfo<AArch64MachineFunctionInfo>(); 19772062f5744557e270a38192554c3126ea5f97434Tim Northover 19872062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 19972062f5744557e270a38192554c3126ea5f97434Tim Northover DebugLoc DL = MBBI->getDebugLoc(); 20072062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 20172062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo &MFI = *MF.getFrameInfo(); 20272062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned RetOpcode = MBBI->getOpcode(); 20372062f5744557e270a38192554c3126ea5f97434Tim Northover 20472062f5744557e270a38192554c3126ea5f97434Tim Northover // Initial and residual are named for consitency with the prologue. Note that 20572062f5744557e270a38192554c3126ea5f97434Tim Northover // in the epilogue, the residual adjustment is executed first. 20672062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t NumInitialBytes = FuncInfo->getInitialStackAdjust(); 20772062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t NumResidualBytes = MFI.getStackSize() - NumInitialBytes; 20872062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t ArgumentPopSize = 0; 20972062f5744557e270a38192554c3126ea5f97434Tim Northover if (RetOpcode == AArch64::TC_RETURNdi || 21072062f5744557e270a38192554c3126ea5f97434Tim Northover RetOpcode == AArch64::TC_RETURNxi) { 21172062f5744557e270a38192554c3126ea5f97434Tim Northover MachineOperand &JumpTarget = MBBI->getOperand(0); 21272062f5744557e270a38192554c3126ea5f97434Tim Northover MachineOperand &StackAdjust = MBBI->getOperand(1); 21372062f5744557e270a38192554c3126ea5f97434Tim Northover 21472062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstrBuilder MIB; 21572062f5744557e270a38192554c3126ea5f97434Tim Northover if (RetOpcode == AArch64::TC_RETURNdi) { 21672062f5744557e270a38192554c3126ea5f97434Tim Northover MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::TAIL_Bimm)); 21772062f5744557e270a38192554c3126ea5f97434Tim Northover if (JumpTarget.isGlobal()) { 21872062f5744557e270a38192554c3126ea5f97434Tim Northover MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 21972062f5744557e270a38192554c3126ea5f97434Tim Northover JumpTarget.getTargetFlags()); 22072062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 22172062f5744557e270a38192554c3126ea5f97434Tim Northover assert(JumpTarget.isSymbol() && "unexpected tail call destination"); 22272062f5744557e270a38192554c3126ea5f97434Tim Northover MIB.addExternalSymbol(JumpTarget.getSymbolName(), 22372062f5744557e270a38192554c3126ea5f97434Tim Northover JumpTarget.getTargetFlags()); 22472062f5744557e270a38192554c3126ea5f97434Tim Northover } 22572062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 22672062f5744557e270a38192554c3126ea5f97434Tim Northover assert(RetOpcode == AArch64::TC_RETURNxi && JumpTarget.isReg() 22772062f5744557e270a38192554c3126ea5f97434Tim Northover && "Unexpected tail call"); 22872062f5744557e270a38192554c3126ea5f97434Tim Northover 22972062f5744557e270a38192554c3126ea5f97434Tim Northover MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::TAIL_BRx)); 23072062f5744557e270a38192554c3126ea5f97434Tim Northover MIB.addReg(JumpTarget.getReg(), RegState::Kill); 23172062f5744557e270a38192554c3126ea5f97434Tim Northover } 23272062f5744557e270a38192554c3126ea5f97434Tim Northover 23372062f5744557e270a38192554c3126ea5f97434Tim Northover // Add the extra operands onto the new tail call instruction even though 23472062f5744557e270a38192554c3126ea5f97434Tim Northover // they're not used directly (so that liveness is tracked properly etc). 23572062f5744557e270a38192554c3126ea5f97434Tim Northover for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i) 23672062f5744557e270a38192554c3126ea5f97434Tim Northover MIB->addOperand(MBBI->getOperand(i)); 23772062f5744557e270a38192554c3126ea5f97434Tim Northover 23872062f5744557e270a38192554c3126ea5f97434Tim Northover 23972062f5744557e270a38192554c3126ea5f97434Tim Northover // Delete the pseudo instruction TC_RETURN. 24072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr *NewMI = prior(MBBI); 24172062f5744557e270a38192554c3126ea5f97434Tim Northover MBB.erase(MBBI); 24272062f5744557e270a38192554c3126ea5f97434Tim Northover MBBI = NewMI; 24372062f5744557e270a38192554c3126ea5f97434Tim Northover 24472062f5744557e270a38192554c3126ea5f97434Tim Northover // For a tail-call in a callee-pops-arguments environment, some or all of 24572062f5744557e270a38192554c3126ea5f97434Tim Northover // the stack may actually be in use for the call's arguments, this is 24672062f5744557e270a38192554c3126ea5f97434Tim Northover // calculated during LowerCall and consumed here... 24772062f5744557e270a38192554c3126ea5f97434Tim Northover ArgumentPopSize = StackAdjust.getImm(); 24872062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 24972062f5744557e270a38192554c3126ea5f97434Tim Northover // ... otherwise the amount to pop is *all* of the argument space, 25072062f5744557e270a38192554c3126ea5f97434Tim Northover // conveniently stored in the MachineFunctionInfo by 25172062f5744557e270a38192554c3126ea5f97434Tim Northover // LowerFormalArguments. This will, of course, be zero for the C calling 25272062f5744557e270a38192554c3126ea5f97434Tim Northover // convention. 25372062f5744557e270a38192554c3126ea5f97434Tim Northover ArgumentPopSize = FuncInfo->getArgumentStackToRestore(); 25472062f5744557e270a38192554c3126ea5f97434Tim Northover } 25572062f5744557e270a38192554c3126ea5f97434Tim Northover 25672062f5744557e270a38192554c3126ea5f97434Tim Northover assert(NumInitialBytes % 16 == 0 && NumResidualBytes % 16 == 0 25772062f5744557e270a38192554c3126ea5f97434Tim Northover && "refusing to adjust stack by misaligned amt"); 25872062f5744557e270a38192554c3126ea5f97434Tim Northover 25972062f5744557e270a38192554c3126ea5f97434Tim Northover // We may need to address callee-saved registers differently, so find out the 26072062f5744557e270a38192554c3126ea5f97434Tim Northover // bound on the frame indices. 26172062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 26272062f5744557e270a38192554c3126ea5f97434Tim Northover int MinCSFI = 0; 26372062f5744557e270a38192554c3126ea5f97434Tim Northover int MaxCSFI = -1; 26472062f5744557e270a38192554c3126ea5f97434Tim Northover 26572062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.size()) { 26672062f5744557e270a38192554c3126ea5f97434Tim Northover MinCSFI = CSI[0].getFrameIdx(); 26772062f5744557e270a38192554c3126ea5f97434Tim Northover MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 26872062f5744557e270a38192554c3126ea5f97434Tim Northover } 26972062f5744557e270a38192554c3126ea5f97434Tim Northover 27072062f5744557e270a38192554c3126ea5f97434Tim Northover // The "residual" stack update comes first from this direction and guarantees 27172062f5744557e270a38192554c3126ea5f97434Tim Northover // that SP is NumInitialBytes below its value on function entry, either by a 27272062f5744557e270a38192554c3126ea5f97434Tim Northover // direct update or restoring it from the frame pointer. 27372062f5744557e270a38192554c3126ea5f97434Tim Northover if (NumInitialBytes + ArgumentPopSize != 0) { 27472062f5744557e270a38192554c3126ea5f97434Tim Northover emitSPUpdate(MBB, MBBI, DL, TII, AArch64::X16, 27572062f5744557e270a38192554c3126ea5f97434Tim Northover NumInitialBytes + ArgumentPopSize); 27672062f5744557e270a38192554c3126ea5f97434Tim Northover --MBBI; 27772062f5744557e270a38192554c3126ea5f97434Tim Northover } 27872062f5744557e270a38192554c3126ea5f97434Tim Northover 27972062f5744557e270a38192554c3126ea5f97434Tim Northover 28072062f5744557e270a38192554c3126ea5f97434Tim Northover // MBBI now points to the instruction just past the last callee-saved 28172062f5744557e270a38192554c3126ea5f97434Tim Northover // restoration (either RET/B if NumInitialBytes == 0, or the "ADD sp, sp" 28272062f5744557e270a38192554c3126ea5f97434Tim Northover // otherwise). 28372062f5744557e270a38192554c3126ea5f97434Tim Northover 28472062f5744557e270a38192554c3126ea5f97434Tim Northover // Now we need to find out where to put the bulk of the stack adjustment 28572062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator FirstEpilogue = MBBI; 28672062f5744557e270a38192554c3126ea5f97434Tim Northover while (MBBI != MBB.begin()) { 28772062f5744557e270a38192554c3126ea5f97434Tim Northover --MBBI; 28872062f5744557e270a38192554c3126ea5f97434Tim Northover 28972062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned FrameOp; 29072062f5744557e270a38192554c3126ea5f97434Tim Northover for (FrameOp = 0; FrameOp < MBBI->getNumOperands(); ++FrameOp) { 29172062f5744557e270a38192554c3126ea5f97434Tim Northover if (MBBI->getOperand(FrameOp).isFI()) 29272062f5744557e270a38192554c3126ea5f97434Tim Northover break; 29372062f5744557e270a38192554c3126ea5f97434Tim Northover } 29472062f5744557e270a38192554c3126ea5f97434Tim Northover 29572062f5744557e270a38192554c3126ea5f97434Tim Northover // If this instruction doesn't have a frame index we've reached the end of 29672062f5744557e270a38192554c3126ea5f97434Tim Northover // the callee-save restoration. 29772062f5744557e270a38192554c3126ea5f97434Tim Northover if (FrameOp == MBBI->getNumOperands()) 29872062f5744557e270a38192554c3126ea5f97434Tim Northover break; 29972062f5744557e270a38192554c3126ea5f97434Tim Northover 30072062f5744557e270a38192554c3126ea5f97434Tim Northover // Likewise if it *is* a local reference, but not to a callee-saved object. 30172062f5744557e270a38192554c3126ea5f97434Tim Northover int FrameIdx = MBBI->getOperand(FrameOp).getIndex(); 30272062f5744557e270a38192554c3126ea5f97434Tim Northover if (FrameIdx < MinCSFI || FrameIdx > MaxCSFI) 30372062f5744557e270a38192554c3126ea5f97434Tim Northover break; 30472062f5744557e270a38192554c3126ea5f97434Tim Northover 30572062f5744557e270a38192554c3126ea5f97434Tim Northover FirstEpilogue = MBBI; 30672062f5744557e270a38192554c3126ea5f97434Tim Northover } 30772062f5744557e270a38192554c3126ea5f97434Tim Northover 30872062f5744557e270a38192554c3126ea5f97434Tim Northover if (MF.getFrameInfo()->hasVarSizedObjects()) { 30972062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t StaticFrameBase; 31072062f5744557e270a38192554c3126ea5f97434Tim Northover StaticFrameBase = -(NumInitialBytes + FuncInfo->getFramePointerOffset()); 31172062f5744557e270a38192554c3126ea5f97434Tim Northover emitRegUpdate(MBB, FirstEpilogue, DL, TII, 31272062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64::XSP, AArch64::X29, AArch64::NoRegister, 31372062f5744557e270a38192554c3126ea5f97434Tim Northover StaticFrameBase); 31472062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 31572062f5744557e270a38192554c3126ea5f97434Tim Northover emitSPUpdate(MBB, FirstEpilogue, DL,TII, AArch64::X16, NumResidualBytes); 31672062f5744557e270a38192554c3126ea5f97434Tim Northover } 31772062f5744557e270a38192554c3126ea5f97434Tim Northover} 31872062f5744557e270a38192554c3126ea5f97434Tim Northover 31972062f5744557e270a38192554c3126ea5f97434Tim Northoverint64_t 32072062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::resolveFrameIndexReference(MachineFunction &MF, 32172062f5744557e270a38192554c3126ea5f97434Tim Northover int FrameIndex, 32272062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned &FrameReg, 32372062f5744557e270a38192554c3126ea5f97434Tim Northover int SPAdj, 32472062f5744557e270a38192554c3126ea5f97434Tim Northover bool IsCalleeSaveOp) const { 32572062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64MachineFunctionInfo *FuncInfo = 32672062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getInfo<AArch64MachineFunctionInfo>(); 32772062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo *MFI = MF.getFrameInfo(); 32872062f5744557e270a38192554c3126ea5f97434Tim Northover 32972062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t TopOfFrameOffset = MFI->getObjectOffset(FrameIndex); 33072062f5744557e270a38192554c3126ea5f97434Tim Northover 33172062f5744557e270a38192554c3126ea5f97434Tim Northover assert(!(IsCalleeSaveOp && FuncInfo->getInitialStackAdjust() == 0) 33272062f5744557e270a38192554c3126ea5f97434Tim Northover && "callee-saved register in unexpected place"); 33372062f5744557e270a38192554c3126ea5f97434Tim Northover 33472062f5744557e270a38192554c3126ea5f97434Tim Northover // If the frame for this function is particularly large, we adjust the stack 33572062f5744557e270a38192554c3126ea5f97434Tim Northover // in two phases which means the callee-save related operations see a 33672062f5744557e270a38192554c3126ea5f97434Tim Northover // different (intermediate) stack size. 33772062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t FrameRegPos; 33872062f5744557e270a38192554c3126ea5f97434Tim Northover if (IsCalleeSaveOp) { 33972062f5744557e270a38192554c3126ea5f97434Tim Northover FrameReg = AArch64::XSP; 34072062f5744557e270a38192554c3126ea5f97434Tim Northover FrameRegPos = -static_cast<int64_t>(FuncInfo->getInitialStackAdjust()); 34172062f5744557e270a38192554c3126ea5f97434Tim Northover } else if (useFPForAddressing(MF)) { 34272062f5744557e270a38192554c3126ea5f97434Tim Northover // Have to use the frame pointer since we have no idea where SP is. 34372062f5744557e270a38192554c3126ea5f97434Tim Northover FrameReg = AArch64::X29; 34472062f5744557e270a38192554c3126ea5f97434Tim Northover FrameRegPos = FuncInfo->getFramePointerOffset(); 34572062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 34672062f5744557e270a38192554c3126ea5f97434Tim Northover FrameReg = AArch64::XSP; 34772062f5744557e270a38192554c3126ea5f97434Tim Northover FrameRegPos = -static_cast<int64_t>(MFI->getStackSize()) + SPAdj; 34872062f5744557e270a38192554c3126ea5f97434Tim Northover } 34972062f5744557e270a38192554c3126ea5f97434Tim Northover 35072062f5744557e270a38192554c3126ea5f97434Tim Northover return TopOfFrameOffset - FrameRegPos; 35172062f5744557e270a38192554c3126ea5f97434Tim Northover} 35272062f5744557e270a38192554c3126ea5f97434Tim Northover 35372062f5744557e270a38192554c3126ea5f97434Tim Northovervoid 35472062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 35572062f5744557e270a38192554c3126ea5f97434Tim Northover RegScavenger *RS) const { 35672062f5744557e270a38192554c3126ea5f97434Tim Northover const AArch64RegisterInfo *RegInfo = 35772062f5744557e270a38192554c3126ea5f97434Tim Northover static_cast<const AArch64RegisterInfo *>(MF.getTarget().getRegisterInfo()); 35872062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo *MFI = MF.getFrameInfo(); 35972062f5744557e270a38192554c3126ea5f97434Tim Northover const AArch64InstrInfo &TII = 36072062f5744557e270a38192554c3126ea5f97434Tim Northover *static_cast<const AArch64InstrInfo *>(MF.getTarget().getInstrInfo()); 36172062f5744557e270a38192554c3126ea5f97434Tim Northover 36272062f5744557e270a38192554c3126ea5f97434Tim Northover if (hasFP(MF)) { 36372062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getRegInfo().setPhysRegUsed(AArch64::X29); 36472062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getRegInfo().setPhysRegUsed(AArch64::X30); 36572062f5744557e270a38192554c3126ea5f97434Tim Northover } 36672062f5744557e270a38192554c3126ea5f97434Tim Northover 36772062f5744557e270a38192554c3126ea5f97434Tim Northover // If addressing of local variables is going to be more complicated than 36872062f5744557e270a38192554c3126ea5f97434Tim Northover // shoving a base register and an offset into the instruction then we may well 36972062f5744557e270a38192554c3126ea5f97434Tim Northover // need to scavenge registers. We should either specifically add an 37072062f5744557e270a38192554c3126ea5f97434Tim Northover // callee-save register for this purpose or allocate an extra spill slot. 37172062f5744557e270a38192554c3126ea5f97434Tim Northover bool BigStack = 3723e56b43ac8789da3799069bfca456494c07df872Tim Northover MFI->estimateStackSize(MF) >= TII.estimateRSStackLimit(MF) 37372062f5744557e270a38192554c3126ea5f97434Tim Northover || MFI->hasVarSizedObjects() // Access will be from X29: messes things up 37472062f5744557e270a38192554c3126ea5f97434Tim Northover || (MFI->adjustsStack() && !hasReservedCallFrame(MF)); 37572062f5744557e270a38192554c3126ea5f97434Tim Northover 37672062f5744557e270a38192554c3126ea5f97434Tim Northover if (!BigStack) 37772062f5744557e270a38192554c3126ea5f97434Tim Northover return; 37872062f5744557e270a38192554c3126ea5f97434Tim Northover 37972062f5744557e270a38192554c3126ea5f97434Tim Northover // We certainly need some slack space for the scavenger, preferably an extra 38072062f5744557e270a38192554c3126ea5f97434Tim Northover // register. 38172062f5744557e270a38192554c3126ea5f97434Tim Northover const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(); 38272062f5744557e270a38192554c3126ea5f97434Tim Northover uint16_t ExtraReg = AArch64::NoRegister; 38372062f5744557e270a38192554c3126ea5f97434Tim Northover 38472062f5744557e270a38192554c3126ea5f97434Tim Northover for (unsigned i = 0; CSRegs[i]; ++i) { 38572062f5744557e270a38192554c3126ea5f97434Tim Northover if (AArch64::GPR64RegClass.contains(CSRegs[i]) && 38672062f5744557e270a38192554c3126ea5f97434Tim Northover !MF.getRegInfo().isPhysRegUsed(CSRegs[i])) { 38772062f5744557e270a38192554c3126ea5f97434Tim Northover ExtraReg = CSRegs[i]; 38872062f5744557e270a38192554c3126ea5f97434Tim Northover break; 38972062f5744557e270a38192554c3126ea5f97434Tim Northover } 39072062f5744557e270a38192554c3126ea5f97434Tim Northover } 39172062f5744557e270a38192554c3126ea5f97434Tim Northover 39272062f5744557e270a38192554c3126ea5f97434Tim Northover if (ExtraReg != 0) { 39372062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getRegInfo().setPhysRegUsed(ExtraReg); 39472062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 3953e56b43ac8789da3799069bfca456494c07df872Tim Northover assert(RS && "Expect register scavenger to be available"); 3963e56b43ac8789da3799069bfca456494c07df872Tim Northover 39772062f5744557e270a38192554c3126ea5f97434Tim Northover // Create a stack slot for scavenging purposes. PrologEpilogInserter 39872062f5744557e270a38192554c3126ea5f97434Tim Northover // helpfully places it near either SP or FP for us to avoid 39972062f5744557e270a38192554c3126ea5f97434Tim Northover // infinitely-regression during scavenging. 40072062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterClass *RC = &AArch64::GPR64RegClass; 401dc3beb90178fc316f63790812b22201884eaa017Hal Finkel RS->addScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 40272062f5744557e270a38192554c3126ea5f97434Tim Northover RC->getAlignment(), 40372062f5744557e270a38192554c3126ea5f97434Tim Northover false)); 40472062f5744557e270a38192554c3126ea5f97434Tim Northover } 40572062f5744557e270a38192554c3126ea5f97434Tim Northover} 40672062f5744557e270a38192554c3126ea5f97434Tim Northover 40772062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64FrameLowering::determinePrologueDeath(MachineBasicBlock &MBB, 40872062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned Reg) const { 40972062f5744557e270a38192554c3126ea5f97434Tim Northover // If @llvm.returnaddress is called then it will refer to X30 by some means; 41072062f5744557e270a38192554c3126ea5f97434Tim Northover // the prologue store does not kill the register. 41172062f5744557e270a38192554c3126ea5f97434Tim Northover if (Reg == AArch64::X30) { 41272062f5744557e270a38192554c3126ea5f97434Tim Northover if (MBB.getParent()->getFrameInfo()->isReturnAddressTaken() 41372062f5744557e270a38192554c3126ea5f97434Tim Northover && MBB.getParent()->getRegInfo().isLiveIn(Reg)) 41472062f5744557e270a38192554c3126ea5f97434Tim Northover return false; 41572062f5744557e270a38192554c3126ea5f97434Tim Northover } 41672062f5744557e270a38192554c3126ea5f97434Tim Northover 41772062f5744557e270a38192554c3126ea5f97434Tim Northover // In all other cases, physical registers are dead after they've been saved 41872062f5744557e270a38192554c3126ea5f97434Tim Northover // but live at the beginning of the prologue block. 41972062f5744557e270a38192554c3126ea5f97434Tim Northover MBB.addLiveIn(Reg); 42072062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 42172062f5744557e270a38192554c3126ea5f97434Tim Northover} 42272062f5744557e270a38192554c3126ea5f97434Tim Northover 42372062f5744557e270a38192554c3126ea5f97434Tim Northovervoid 42472062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::emitFrameMemOps(bool isPrologue, MachineBasicBlock &MBB, 42572062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI, 42672062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI, 42772062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *TRI, 4283698dc4d4e7f32fb2d189aaf83a505742c6858e6Craig Topper const LoadStoreMethod PossClasses[], 42972062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned NumClasses) const { 43072062f5744557e270a38192554c3126ea5f97434Tim Northover DebugLoc DL = MBB.findDebugLoc(MBBI); 43172062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFunction &MF = *MBB.getParent(); 43272062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo &MFI = *MF.getFrameInfo(); 43372062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 43472062f5744557e270a38192554c3126ea5f97434Tim Northover 43572062f5744557e270a38192554c3126ea5f97434Tim Northover // A certain amount of implicit contract is present here. The actual stack 43672062f5744557e270a38192554c3126ea5f97434Tim Northover // offsets haven't been allocated officially yet, so for strictly correct code 43772062f5744557e270a38192554c3126ea5f97434Tim Northover // we rely on the fact that the elements of CSI are allocated in order 43872062f5744557e270a38192554c3126ea5f97434Tim Northover // starting at SP, purely as dictated by size and alignment. In practice since 43972062f5744557e270a38192554c3126ea5f97434Tim Northover // this function handles the only accesses to those slots it's not quite so 44072062f5744557e270a38192554c3126ea5f97434Tim Northover // important. 44172062f5744557e270a38192554c3126ea5f97434Tim Northover // 44272062f5744557e270a38192554c3126ea5f97434Tim Northover // We have also ordered the Callee-saved register list in AArch64CallingConv 44372062f5744557e270a38192554c3126ea5f97434Tim Northover // so that the above scheme puts registers in order: in particular we want 44472062f5744557e270a38192554c3126ea5f97434Tim Northover // &X30 to be &X29+8 for an ABI-correct frame record (PCS 5.2.2) 44572062f5744557e270a38192554c3126ea5f97434Tim Northover for (unsigned i = 0, e = CSI.size(); i < e; ++i) { 44672062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned Reg = CSI[i].getReg(); 44772062f5744557e270a38192554c3126ea5f97434Tim Northover 44872062f5744557e270a38192554c3126ea5f97434Tim Northover // First we need to find out which register class the register belongs to so 44972062f5744557e270a38192554c3126ea5f97434Tim Northover // that we can use the correct load/store instrucitons. 45072062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned ClassIdx; 45172062f5744557e270a38192554c3126ea5f97434Tim Northover for (ClassIdx = 0; ClassIdx < NumClasses; ++ClassIdx) { 45272062f5744557e270a38192554c3126ea5f97434Tim Northover if (PossClasses[ClassIdx].RegClass->contains(Reg)) 45372062f5744557e270a38192554c3126ea5f97434Tim Northover break; 45472062f5744557e270a38192554c3126ea5f97434Tim Northover } 45572062f5744557e270a38192554c3126ea5f97434Tim Northover assert(ClassIdx != NumClasses 45672062f5744557e270a38192554c3126ea5f97434Tim Northover && "Asked to store register in unexpected class"); 45772062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterClass &TheClass = *PossClasses[ClassIdx].RegClass; 45872062f5744557e270a38192554c3126ea5f97434Tim Northover 45972062f5744557e270a38192554c3126ea5f97434Tim Northover // Now we need to decide whether it's possible to emit a paired instruction: 46072062f5744557e270a38192554c3126ea5f97434Tim Northover // for this we want the next register to be in the same class. 46172062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstrBuilder NewMI; 46272062f5744557e270a38192554c3126ea5f97434Tim Northover bool Pair = false; 46372062f5744557e270a38192554c3126ea5f97434Tim Northover if (i + 1 < CSI.size() && TheClass.contains(CSI[i+1].getReg())) { 46472062f5744557e270a38192554c3126ea5f97434Tim Northover Pair = true; 46572062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned StLow = 0, StHigh = 0; 46672062f5744557e270a38192554c3126ea5f97434Tim Northover if (isPrologue) { 46772062f5744557e270a38192554c3126ea5f97434Tim Northover // Most of these registers will be live-in to the MBB and killed by our 46872062f5744557e270a38192554c3126ea5f97434Tim Northover // store, though there are exceptions (see determinePrologueDeath). 46972062f5744557e270a38192554c3126ea5f97434Tim Northover StLow = getKillRegState(determinePrologueDeath(MBB, CSI[i+1].getReg())); 47072062f5744557e270a38192554c3126ea5f97434Tim Northover StHigh = getKillRegState(determinePrologueDeath(MBB, CSI[i].getReg())); 47172062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 47272062f5744557e270a38192554c3126ea5f97434Tim Northover StLow = RegState::Define; 47372062f5744557e270a38192554c3126ea5f97434Tim Northover StHigh = RegState::Define; 47472062f5744557e270a38192554c3126ea5f97434Tim Northover } 47572062f5744557e270a38192554c3126ea5f97434Tim Northover 47672062f5744557e270a38192554c3126ea5f97434Tim Northover NewMI = BuildMI(MBB, MBBI, DL, TII.get(PossClasses[ClassIdx].PairOpcode)) 47772062f5744557e270a38192554c3126ea5f97434Tim Northover .addReg(CSI[i+1].getReg(), StLow) 47872062f5744557e270a38192554c3126ea5f97434Tim Northover .addReg(CSI[i].getReg(), StHigh); 47972062f5744557e270a38192554c3126ea5f97434Tim Northover 48072062f5744557e270a38192554c3126ea5f97434Tim Northover // If it's a paired op, we've consumed two registers 48172062f5744557e270a38192554c3126ea5f97434Tim Northover ++i; 48272062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 48372062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned State; 48472062f5744557e270a38192554c3126ea5f97434Tim Northover if (isPrologue) { 48572062f5744557e270a38192554c3126ea5f97434Tim Northover State = getKillRegState(determinePrologueDeath(MBB, CSI[i].getReg())); 48672062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 48772062f5744557e270a38192554c3126ea5f97434Tim Northover State = RegState::Define; 48872062f5744557e270a38192554c3126ea5f97434Tim Northover } 48972062f5744557e270a38192554c3126ea5f97434Tim Northover 490dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover NewMI = BuildMI(MBB, MBBI, DL, 491dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover TII.get(PossClasses[ClassIdx].SingleOpcode)) 49272062f5744557e270a38192554c3126ea5f97434Tim Northover .addReg(CSI[i].getReg(), State); 49372062f5744557e270a38192554c3126ea5f97434Tim Northover } 49472062f5744557e270a38192554c3126ea5f97434Tim Northover 49572062f5744557e270a38192554c3126ea5f97434Tim Northover // Note that the FrameIdx refers to the second register in a pair: it will 49672062f5744557e270a38192554c3126ea5f97434Tim Northover // be allocated the smaller numeric address and so is the one an LDP/STP 49772062f5744557e270a38192554c3126ea5f97434Tim Northover // address must use. 49872062f5744557e270a38192554c3126ea5f97434Tim Northover int FrameIdx = CSI[i].getFrameIdx(); 49972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineMemOperand::MemOperandFlags Flags; 50072062f5744557e270a38192554c3126ea5f97434Tim Northover Flags = isPrologue ? MachineMemOperand::MOStore : MachineMemOperand::MOLoad; 50172062f5744557e270a38192554c3126ea5f97434Tim Northover MachineMemOperand *MMO = 50272062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 503dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover Flags, 504dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover Pair ? TheClass.getSize() * 2 : TheClass.getSize(), 505dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover MFI.getObjectAlignment(FrameIdx)); 50672062f5744557e270a38192554c3126ea5f97434Tim Northover 50772062f5744557e270a38192554c3126ea5f97434Tim Northover NewMI.addFrameIndex(FrameIdx) 50872062f5744557e270a38192554c3126ea5f97434Tim Northover .addImm(0) // address-register offset 50972062f5744557e270a38192554c3126ea5f97434Tim Northover .addMemOperand(MMO); 51072062f5744557e270a38192554c3126ea5f97434Tim Northover 51172062f5744557e270a38192554c3126ea5f97434Tim Northover if (isPrologue) 51272062f5744557e270a38192554c3126ea5f97434Tim Northover NewMI.setMIFlags(MachineInstr::FrameSetup); 51372062f5744557e270a38192554c3126ea5f97434Tim Northover 51472062f5744557e270a38192554c3126ea5f97434Tim Northover // For aesthetic reasons, during an epilogue we want to emit complementary 51572062f5744557e270a38192554c3126ea5f97434Tim Northover // operations to the prologue, but in the opposite order. So we still 51672062f5744557e270a38192554c3126ea5f97434Tim Northover // iterate through the CalleeSavedInfo list in order, but we put the 51772062f5744557e270a38192554c3126ea5f97434Tim Northover // instructions successively earlier in the MBB. 51872062f5744557e270a38192554c3126ea5f97434Tim Northover if (!isPrologue) 51972062f5744557e270a38192554c3126ea5f97434Tim Northover --MBBI; 52072062f5744557e270a38192554c3126ea5f97434Tim Northover } 52172062f5744557e270a38192554c3126ea5f97434Tim Northover} 52272062f5744557e270a38192554c3126ea5f97434Tim Northover 52372062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 52472062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 52572062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI, 52672062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI, 52772062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *TRI) const { 52872062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.empty()) 52972062f5744557e270a38192554c3126ea5f97434Tim Northover return false; 53072062f5744557e270a38192554c3126ea5f97434Tim Northover 5313698dc4d4e7f32fb2d189aaf83a505742c6858e6Craig Topper static const LoadStoreMethod PossibleClasses[] = { 53272062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::GPR64RegClass, AArch64::LSPair64_STR, AArch64::LS64_STR}, 53372062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::FPR64RegClass, AArch64::LSFPPair64_STR, AArch64::LSFP64_STR}, 53472062f5744557e270a38192554c3126ea5f97434Tim Northover }; 5353698dc4d4e7f32fb2d189aaf83a505742c6858e6Craig Topper const unsigned NumClasses = llvm::array_lengthof(PossibleClasses); 53672062f5744557e270a38192554c3126ea5f97434Tim Northover 53772062f5744557e270a38192554c3126ea5f97434Tim Northover emitFrameMemOps(/* isPrologue = */ true, MBB, MBBI, CSI, TRI, 53872062f5744557e270a38192554c3126ea5f97434Tim Northover PossibleClasses, NumClasses); 53972062f5744557e270a38192554c3126ea5f97434Tim Northover 54072062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 54172062f5744557e270a38192554c3126ea5f97434Tim Northover} 54272062f5744557e270a38192554c3126ea5f97434Tim Northover 54372062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 54472062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 54572062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI, 54672062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI, 54772062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *TRI) const { 54872062f5744557e270a38192554c3126ea5f97434Tim Northover 54972062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.empty()) 55072062f5744557e270a38192554c3126ea5f97434Tim Northover return false; 55172062f5744557e270a38192554c3126ea5f97434Tim Northover 5523698dc4d4e7f32fb2d189aaf83a505742c6858e6Craig Topper static const LoadStoreMethod PossibleClasses[] = { 55372062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::GPR64RegClass, AArch64::LSPair64_LDR, AArch64::LS64_LDR}, 55472062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::FPR64RegClass, AArch64::LSFPPair64_LDR, AArch64::LSFP64_LDR}, 55572062f5744557e270a38192554c3126ea5f97434Tim Northover }; 5563698dc4d4e7f32fb2d189aaf83a505742c6858e6Craig Topper const unsigned NumClasses = llvm::array_lengthof(PossibleClasses); 55772062f5744557e270a38192554c3126ea5f97434Tim Northover 55872062f5744557e270a38192554c3126ea5f97434Tim Northover emitFrameMemOps(/* isPrologue = */ false, MBB, MBBI, CSI, TRI, 55972062f5744557e270a38192554c3126ea5f97434Tim Northover PossibleClasses, NumClasses); 56072062f5744557e270a38192554c3126ea5f97434Tim Northover 56172062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 56272062f5744557e270a38192554c3126ea5f97434Tim Northover} 56372062f5744557e270a38192554c3126ea5f97434Tim Northover 56472062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 56572062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::hasFP(const MachineFunction &MF) const { 56672062f5744557e270a38192554c3126ea5f97434Tim Northover const MachineFrameInfo *MFI = MF.getFrameInfo(); 56772062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *RI = MF.getTarget().getRegisterInfo(); 56872062f5744557e270a38192554c3126ea5f97434Tim Northover 56972062f5744557e270a38192554c3126ea5f97434Tim Northover // This is a decision of ABI compliance. The AArch64 PCS gives various options 57072062f5744557e270a38192554c3126ea5f97434Tim Northover // for conformance, and even at the most stringent level more or less permits 57172062f5744557e270a38192554c3126ea5f97434Tim Northover // elimination for leaf functions because there's no loss of functionality 57272062f5744557e270a38192554c3126ea5f97434Tim Northover // (for debugging etc).. 57372062f5744557e270a38192554c3126ea5f97434Tim Northover if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI->hasCalls()) 57472062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 57572062f5744557e270a38192554c3126ea5f97434Tim Northover 57672062f5744557e270a38192554c3126ea5f97434Tim Northover // The following are hard-limits: incorrect code will be generated if we try 57772062f5744557e270a38192554c3126ea5f97434Tim Northover // to omit the frame. 57872062f5744557e270a38192554c3126ea5f97434Tim Northover return (RI->needsStackRealignment(MF) || 57972062f5744557e270a38192554c3126ea5f97434Tim Northover MFI->hasVarSizedObjects() || 58072062f5744557e270a38192554c3126ea5f97434Tim Northover MFI->isFrameAddressTaken()); 58172062f5744557e270a38192554c3126ea5f97434Tim Northover} 58272062f5744557e270a38192554c3126ea5f97434Tim Northover 58372062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 58472062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::useFPForAddressing(const MachineFunction &MF) const { 58572062f5744557e270a38192554c3126ea5f97434Tim Northover return MF.getFrameInfo()->hasVarSizedObjects(); 58672062f5744557e270a38192554c3126ea5f97434Tim Northover} 58772062f5744557e270a38192554c3126ea5f97434Tim Northover 58872062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 58972062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 59072062f5744557e270a38192554c3126ea5f97434Tim Northover const MachineFrameInfo *MFI = MF.getFrameInfo(); 59172062f5744557e270a38192554c3126ea5f97434Tim Northover 59272062f5744557e270a38192554c3126ea5f97434Tim Northover // Of the various reasons for having a frame pointer, it's actually only 59372062f5744557e270a38192554c3126ea5f97434Tim Northover // variable-sized objects that prevent reservation of a call frame. 59472062f5744557e270a38192554c3126ea5f97434Tim Northover return !(hasFP(MF) && MFI->hasVarSizedObjects()); 59572062f5744557e270a38192554c3126ea5f97434Tim Northover} 596700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 597700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid 598700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyAArch64FrameLowering::eliminateCallFramePseudoInstr( 599700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineFunction &MF, 600700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock &MBB, 601700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator MI) const { 602700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky const AArch64InstrInfo &TII = 603700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky *static_cast<const AArch64InstrInfo *>(MF.getTarget().getInstrInfo()); 604700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky DebugLoc dl = MI->getDebugLoc(); 605700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky int Opcode = MI->getOpcode(); 606700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode(); 607700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t CalleePopAmount = IsDestroy ? MI->getOperand(1).getImm() : 0; 608700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 609700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (!hasReservedCallFrame(MF)) { 610700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned Align = getStackAlignment(); 611700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 612700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky int64_t Amount = MI->getOperand(0).getImm(); 613700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount = RoundUpToAlignment(Amount, Align); 614700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (!IsDestroy) Amount = -Amount; 615700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 616700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it 617700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // doesn't have to pop anything), then the first operand will be zero too so 618700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // this adjustment is a no-op. 619700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (CalleePopAmount == 0) { 620700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // FIXME: in-function stack adjustment for calls is limited to 12-bits 621700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // because there's no guaranteed temporary register available. Mostly call 622700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // frames will be allocated at the start of a function so this is OK, but 623700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // it is a limitation that needs dealing with. 624700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky assert(Amount > -0xfff && Amount < 0xfff && "call frame too large"); 625700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, Amount); 626700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 627700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else if (CalleePopAmount != 0) { 628700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If the calling convention demands that the callee pops arguments from the 629700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // stack, we want to add it back if we have a reserved call frame. 630700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky assert(CalleePopAmount < 0xfff && "call frame too large"); 631700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, -CalleePopAmount); 632700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 633700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 634700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.erase(MI); 635700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 636