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(); 5772062f5744557e270a38192554c3126ea5f97434Tim Northover std::vector<MachineMove> &Moves = MMI.getFrameMoves(); 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); 10072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Src(AArch64::XSP, NumInitialBytes); 10172062f5744557e270a38192554c3126ea5f97434Tim Northover Moves.push_back(MachineMove(SPLabel, Dst, Src)); 10272062f5744557e270a38192554c3126ea5f97434Tim Northover } 10372062f5744557e270a38192554c3126ea5f97434Tim Northover 10472062f5744557e270a38192554c3126ea5f97434Tim Northover // Otherwise we need to set the frame pointer and/or add a second stack 10572062f5744557e270a38192554c3126ea5f97434Tim Northover // adjustment. 10672062f5744557e270a38192554c3126ea5f97434Tim Northover 10772062f5744557e270a38192554c3126ea5f97434Tim Northover bool FPNeedsSetting = hasFP(MF); 10872062f5744557e270a38192554c3126ea5f97434Tim Northover for (; MBBI != MBB.end(); ++MBBI) { 10972062f5744557e270a38192554c3126ea5f97434Tim Northover // Note that this search makes strong assumptions about the operation used 11072062f5744557e270a38192554c3126ea5f97434Tim Northover // to store the frame-pointer: it must be "STP x29, x30, ...". This could 11172062f5744557e270a38192554c3126ea5f97434Tim Northover // change in future, but until then there's no point in implementing 11272062f5744557e270a38192554c3126ea5f97434Tim Northover // untestable more generic cases. 11372062f5744557e270a38192554c3126ea5f97434Tim Northover if (FPNeedsSetting && MBBI->getOpcode() == AArch64::LSPair64_STR 11472062f5744557e270a38192554c3126ea5f97434Tim Northover && MBBI->getOperand(0).getReg() == AArch64::X29) { 11572062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t X29FrameIdx = MBBI->getOperand(2).getIndex(); 11672062f5744557e270a38192554c3126ea5f97434Tim Northover FuncInfo->setFramePointerOffset(MFI->getObjectOffset(X29FrameIdx)); 11772062f5744557e270a38192554c3126ea5f97434Tim Northover 11872062f5744557e270a38192554c3126ea5f97434Tim Northover ++MBBI; 11972062f5744557e270a38192554c3126ea5f97434Tim Northover emitRegUpdate(MBB, MBBI, DL, TII, AArch64::X29, AArch64::XSP, 12072062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64::X29, 12172062f5744557e270a38192554c3126ea5f97434Tim Northover NumInitialBytes + MFI->getObjectOffset(X29FrameIdx), 12272062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr::FrameSetup); 12372062f5744557e270a38192554c3126ea5f97434Tim Northover 12472062f5744557e270a38192554c3126ea5f97434Tim Northover // The offset adjustment used when emitting debugging locations relative 12572062f5744557e270a38192554c3126ea5f97434Tim Northover // to whatever frame base is set. AArch64 uses the default frame base (FP 12672062f5744557e270a38192554c3126ea5f97434Tim Northover // or SP) and this adjusts the calculations to be correct. 12772062f5744557e270a38192554c3126ea5f97434Tim Northover MFI->setOffsetAdjustment(- MFI->getObjectOffset(X29FrameIdx) 12872062f5744557e270a38192554c3126ea5f97434Tim Northover - MFI->getStackSize()); 12972062f5744557e270a38192554c3126ea5f97434Tim Northover 13072062f5744557e270a38192554c3126ea5f97434Tim Northover if (NeedsFrameMoves) { 13172062f5744557e270a38192554c3126ea5f97434Tim Northover MCSymbol *FPLabel = MMI.getContext().CreateTempSymbol(); 13272062f5744557e270a38192554c3126ea5f97434Tim Northover BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::PROLOG_LABEL)) 13372062f5744557e270a38192554c3126ea5f97434Tim Northover .addSym(FPLabel); 13472062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Dst(MachineLocation::VirtualFP); 13572062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Src(AArch64::X29, -MFI->getObjectOffset(X29FrameIdx)); 13672062f5744557e270a38192554c3126ea5f97434Tim Northover Moves.push_back(MachineMove(FPLabel, Dst, Src)); 13772062f5744557e270a38192554c3126ea5f97434Tim Northover } 13872062f5744557e270a38192554c3126ea5f97434Tim Northover 13972062f5744557e270a38192554c3126ea5f97434Tim Northover FPNeedsSetting = false; 14072062f5744557e270a38192554c3126ea5f97434Tim Northover } 14172062f5744557e270a38192554c3126ea5f97434Tim Northover 14272062f5744557e270a38192554c3126ea5f97434Tim Northover if (!MBBI->getFlag(MachineInstr::FrameSetup)) 14372062f5744557e270a38192554c3126ea5f97434Tim Northover break; 14472062f5744557e270a38192554c3126ea5f97434Tim Northover } 14572062f5744557e270a38192554c3126ea5f97434Tim Northover 14672062f5744557e270a38192554c3126ea5f97434Tim Northover assert(!FPNeedsSetting && "Frame pointer couldn't be set"); 14772062f5744557e270a38192554c3126ea5f97434Tim Northover 14872062f5744557e270a38192554c3126ea5f97434Tim Northover emitSPUpdate(MBB, MBBI, DL, TII, AArch64::X16, -NumResidualBytes, 14972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr::FrameSetup); 15072062f5744557e270a38192554c3126ea5f97434Tim Northover 15172062f5744557e270a38192554c3126ea5f97434Tim Northover // Now we emit the rest of the frame setup information, if necessary: we've 15272062f5744557e270a38192554c3126ea5f97434Tim Northover // already noted the FP and initial SP moves so we're left with the prologue's 15372062f5744557e270a38192554c3126ea5f97434Tim Northover // final SP update and callee-saved register locations. 15472062f5744557e270a38192554c3126ea5f97434Tim Northover if (!NeedsFrameMoves) 15572062f5744557e270a38192554c3126ea5f97434Tim Northover return; 15672062f5744557e270a38192554c3126ea5f97434Tim Northover 15772062f5744557e270a38192554c3126ea5f97434Tim Northover // Reuse the label if appropriate, so create it in this outer scope. 15872062f5744557e270a38192554c3126ea5f97434Tim Northover MCSymbol *CSLabel = 0; 15972062f5744557e270a38192554c3126ea5f97434Tim Northover 16072062f5744557e270a38192554c3126ea5f97434Tim Northover // The rest of the stack adjustment 16172062f5744557e270a38192554c3126ea5f97434Tim Northover if (!hasFP(MF) && NumResidualBytes) { 16272062f5744557e270a38192554c3126ea5f97434Tim Northover CSLabel = MMI.getContext().CreateTempSymbol(); 16372062f5744557e270a38192554c3126ea5f97434Tim Northover BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::PROLOG_LABEL)) 16472062f5744557e270a38192554c3126ea5f97434Tim Northover .addSym(CSLabel); 16572062f5744557e270a38192554c3126ea5f97434Tim Northover 16672062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Dst(MachineLocation::VirtualFP); 16772062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Src(AArch64::XSP, NumResidualBytes + NumInitialBytes); 16872062f5744557e270a38192554c3126ea5f97434Tim Northover Moves.push_back(MachineMove(CSLabel, Dst, Src)); 16972062f5744557e270a38192554c3126ea5f97434Tim Northover } 17072062f5744557e270a38192554c3126ea5f97434Tim Northover 17172062f5744557e270a38192554c3126ea5f97434Tim Northover // And any callee-saved registers (it's fine to leave them to the end here, 17272062f5744557e270a38192554c3126ea5f97434Tim Northover // because the old values are still valid at this point. 17372062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 17472062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.size()) { 17572062f5744557e270a38192554c3126ea5f97434Tim Northover if (!CSLabel) { 17672062f5744557e270a38192554c3126ea5f97434Tim Northover CSLabel = MMI.getContext().CreateTempSymbol(); 17772062f5744557e270a38192554c3126ea5f97434Tim Northover BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::PROLOG_LABEL)) 17872062f5744557e270a38192554c3126ea5f97434Tim Northover .addSym(CSLabel); 17972062f5744557e270a38192554c3126ea5f97434Tim Northover } 18072062f5744557e270a38192554c3126ea5f97434Tim Northover 18172062f5744557e270a38192554c3126ea5f97434Tim Northover for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(), 18272062f5744557e270a38192554c3126ea5f97434Tim Northover E = CSI.end(); I != E; ++I) { 183dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover MachineLocation Dst(MachineLocation::VirtualFP, 184dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover MFI->getObjectOffset(I->getFrameIdx())); 18572062f5744557e270a38192554c3126ea5f97434Tim Northover MachineLocation Src(I->getReg()); 18672062f5744557e270a38192554c3126ea5f97434Tim Northover Moves.push_back(MachineMove(CSLabel, Dst, Src)); 18772062f5744557e270a38192554c3126ea5f97434Tim Northover } 18872062f5744557e270a38192554c3126ea5f97434Tim Northover } 18972062f5744557e270a38192554c3126ea5f97434Tim Northover} 19072062f5744557e270a38192554c3126ea5f97434Tim Northover 19172062f5744557e270a38192554c3126ea5f97434Tim Northovervoid 19272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::emitEpilogue(MachineFunction &MF, 19372062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock &MBB) const { 19472062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64MachineFunctionInfo *FuncInfo = 19572062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getInfo<AArch64MachineFunctionInfo>(); 19672062f5744557e270a38192554c3126ea5f97434Tim Northover 19772062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 19872062f5744557e270a38192554c3126ea5f97434Tim Northover DebugLoc DL = MBBI->getDebugLoc(); 19972062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 20072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo &MFI = *MF.getFrameInfo(); 20172062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned RetOpcode = MBBI->getOpcode(); 20272062f5744557e270a38192554c3126ea5f97434Tim Northover 20372062f5744557e270a38192554c3126ea5f97434Tim Northover // Initial and residual are named for consitency with the prologue. Note that 20472062f5744557e270a38192554c3126ea5f97434Tim Northover // in the epilogue, the residual adjustment is executed first. 20572062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t NumInitialBytes = FuncInfo->getInitialStackAdjust(); 20672062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t NumResidualBytes = MFI.getStackSize() - NumInitialBytes; 20772062f5744557e270a38192554c3126ea5f97434Tim Northover uint64_t ArgumentPopSize = 0; 20872062f5744557e270a38192554c3126ea5f97434Tim Northover if (RetOpcode == AArch64::TC_RETURNdi || 20972062f5744557e270a38192554c3126ea5f97434Tim Northover RetOpcode == AArch64::TC_RETURNxi) { 21072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineOperand &JumpTarget = MBBI->getOperand(0); 21172062f5744557e270a38192554c3126ea5f97434Tim Northover MachineOperand &StackAdjust = MBBI->getOperand(1); 21272062f5744557e270a38192554c3126ea5f97434Tim Northover 21372062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstrBuilder MIB; 21472062f5744557e270a38192554c3126ea5f97434Tim Northover if (RetOpcode == AArch64::TC_RETURNdi) { 21572062f5744557e270a38192554c3126ea5f97434Tim Northover MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::TAIL_Bimm)); 21672062f5744557e270a38192554c3126ea5f97434Tim Northover if (JumpTarget.isGlobal()) { 21772062f5744557e270a38192554c3126ea5f97434Tim Northover MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 21872062f5744557e270a38192554c3126ea5f97434Tim Northover JumpTarget.getTargetFlags()); 21972062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 22072062f5744557e270a38192554c3126ea5f97434Tim Northover assert(JumpTarget.isSymbol() && "unexpected tail call destination"); 22172062f5744557e270a38192554c3126ea5f97434Tim Northover MIB.addExternalSymbol(JumpTarget.getSymbolName(), 22272062f5744557e270a38192554c3126ea5f97434Tim Northover JumpTarget.getTargetFlags()); 22372062f5744557e270a38192554c3126ea5f97434Tim Northover } 22472062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 22572062f5744557e270a38192554c3126ea5f97434Tim Northover assert(RetOpcode == AArch64::TC_RETURNxi && JumpTarget.isReg() 22672062f5744557e270a38192554c3126ea5f97434Tim Northover && "Unexpected tail call"); 22772062f5744557e270a38192554c3126ea5f97434Tim Northover 22872062f5744557e270a38192554c3126ea5f97434Tim Northover MIB = BuildMI(MBB, MBBI, DL, TII.get(AArch64::TAIL_BRx)); 22972062f5744557e270a38192554c3126ea5f97434Tim Northover MIB.addReg(JumpTarget.getReg(), RegState::Kill); 23072062f5744557e270a38192554c3126ea5f97434Tim Northover } 23172062f5744557e270a38192554c3126ea5f97434Tim Northover 23272062f5744557e270a38192554c3126ea5f97434Tim Northover // Add the extra operands onto the new tail call instruction even though 23372062f5744557e270a38192554c3126ea5f97434Tim Northover // they're not used directly (so that liveness is tracked properly etc). 23472062f5744557e270a38192554c3126ea5f97434Tim Northover for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i) 23572062f5744557e270a38192554c3126ea5f97434Tim Northover MIB->addOperand(MBBI->getOperand(i)); 23672062f5744557e270a38192554c3126ea5f97434Tim Northover 23772062f5744557e270a38192554c3126ea5f97434Tim Northover 23872062f5744557e270a38192554c3126ea5f97434Tim Northover // Delete the pseudo instruction TC_RETURN. 23972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstr *NewMI = prior(MBBI); 24072062f5744557e270a38192554c3126ea5f97434Tim Northover MBB.erase(MBBI); 24172062f5744557e270a38192554c3126ea5f97434Tim Northover MBBI = NewMI; 24272062f5744557e270a38192554c3126ea5f97434Tim Northover 24372062f5744557e270a38192554c3126ea5f97434Tim Northover // For a tail-call in a callee-pops-arguments environment, some or all of 24472062f5744557e270a38192554c3126ea5f97434Tim Northover // the stack may actually be in use for the call's arguments, this is 24572062f5744557e270a38192554c3126ea5f97434Tim Northover // calculated during LowerCall and consumed here... 24672062f5744557e270a38192554c3126ea5f97434Tim Northover ArgumentPopSize = StackAdjust.getImm(); 24772062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 24872062f5744557e270a38192554c3126ea5f97434Tim Northover // ... otherwise the amount to pop is *all* of the argument space, 24972062f5744557e270a38192554c3126ea5f97434Tim Northover // conveniently stored in the MachineFunctionInfo by 25072062f5744557e270a38192554c3126ea5f97434Tim Northover // LowerFormalArguments. This will, of course, be zero for the C calling 25172062f5744557e270a38192554c3126ea5f97434Tim Northover // convention. 25272062f5744557e270a38192554c3126ea5f97434Tim Northover ArgumentPopSize = FuncInfo->getArgumentStackToRestore(); 25372062f5744557e270a38192554c3126ea5f97434Tim Northover } 25472062f5744557e270a38192554c3126ea5f97434Tim Northover 25572062f5744557e270a38192554c3126ea5f97434Tim Northover assert(NumInitialBytes % 16 == 0 && NumResidualBytes % 16 == 0 25672062f5744557e270a38192554c3126ea5f97434Tim Northover && "refusing to adjust stack by misaligned amt"); 25772062f5744557e270a38192554c3126ea5f97434Tim Northover 25872062f5744557e270a38192554c3126ea5f97434Tim Northover // We may need to address callee-saved registers differently, so find out the 25972062f5744557e270a38192554c3126ea5f97434Tim Northover // bound on the frame indices. 26072062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 26172062f5744557e270a38192554c3126ea5f97434Tim Northover int MinCSFI = 0; 26272062f5744557e270a38192554c3126ea5f97434Tim Northover int MaxCSFI = -1; 26372062f5744557e270a38192554c3126ea5f97434Tim Northover 26472062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.size()) { 26572062f5744557e270a38192554c3126ea5f97434Tim Northover MinCSFI = CSI[0].getFrameIdx(); 26672062f5744557e270a38192554c3126ea5f97434Tim Northover MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 26772062f5744557e270a38192554c3126ea5f97434Tim Northover } 26872062f5744557e270a38192554c3126ea5f97434Tim Northover 26972062f5744557e270a38192554c3126ea5f97434Tim Northover // The "residual" stack update comes first from this direction and guarantees 27072062f5744557e270a38192554c3126ea5f97434Tim Northover // that SP is NumInitialBytes below its value on function entry, either by a 27172062f5744557e270a38192554c3126ea5f97434Tim Northover // direct update or restoring it from the frame pointer. 27272062f5744557e270a38192554c3126ea5f97434Tim Northover if (NumInitialBytes + ArgumentPopSize != 0) { 27372062f5744557e270a38192554c3126ea5f97434Tim Northover emitSPUpdate(MBB, MBBI, DL, TII, AArch64::X16, 27472062f5744557e270a38192554c3126ea5f97434Tim Northover NumInitialBytes + ArgumentPopSize); 27572062f5744557e270a38192554c3126ea5f97434Tim Northover --MBBI; 27672062f5744557e270a38192554c3126ea5f97434Tim Northover } 27772062f5744557e270a38192554c3126ea5f97434Tim Northover 27872062f5744557e270a38192554c3126ea5f97434Tim Northover 27972062f5744557e270a38192554c3126ea5f97434Tim Northover // MBBI now points to the instruction just past the last callee-saved 28072062f5744557e270a38192554c3126ea5f97434Tim Northover // restoration (either RET/B if NumInitialBytes == 0, or the "ADD sp, sp" 28172062f5744557e270a38192554c3126ea5f97434Tim Northover // otherwise). 28272062f5744557e270a38192554c3126ea5f97434Tim Northover 28372062f5744557e270a38192554c3126ea5f97434Tim Northover // Now we need to find out where to put the bulk of the stack adjustment 28472062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator FirstEpilogue = MBBI; 28572062f5744557e270a38192554c3126ea5f97434Tim Northover while (MBBI != MBB.begin()) { 28672062f5744557e270a38192554c3126ea5f97434Tim Northover --MBBI; 28772062f5744557e270a38192554c3126ea5f97434Tim Northover 28872062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned FrameOp; 28972062f5744557e270a38192554c3126ea5f97434Tim Northover for (FrameOp = 0; FrameOp < MBBI->getNumOperands(); ++FrameOp) { 29072062f5744557e270a38192554c3126ea5f97434Tim Northover if (MBBI->getOperand(FrameOp).isFI()) 29172062f5744557e270a38192554c3126ea5f97434Tim Northover break; 29272062f5744557e270a38192554c3126ea5f97434Tim Northover } 29372062f5744557e270a38192554c3126ea5f97434Tim Northover 29472062f5744557e270a38192554c3126ea5f97434Tim Northover // If this instruction doesn't have a frame index we've reached the end of 29572062f5744557e270a38192554c3126ea5f97434Tim Northover // the callee-save restoration. 29672062f5744557e270a38192554c3126ea5f97434Tim Northover if (FrameOp == MBBI->getNumOperands()) 29772062f5744557e270a38192554c3126ea5f97434Tim Northover break; 29872062f5744557e270a38192554c3126ea5f97434Tim Northover 29972062f5744557e270a38192554c3126ea5f97434Tim Northover // Likewise if it *is* a local reference, but not to a callee-saved object. 30072062f5744557e270a38192554c3126ea5f97434Tim Northover int FrameIdx = MBBI->getOperand(FrameOp).getIndex(); 30172062f5744557e270a38192554c3126ea5f97434Tim Northover if (FrameIdx < MinCSFI || FrameIdx > MaxCSFI) 30272062f5744557e270a38192554c3126ea5f97434Tim Northover break; 30372062f5744557e270a38192554c3126ea5f97434Tim Northover 30472062f5744557e270a38192554c3126ea5f97434Tim Northover FirstEpilogue = MBBI; 30572062f5744557e270a38192554c3126ea5f97434Tim Northover } 30672062f5744557e270a38192554c3126ea5f97434Tim Northover 30772062f5744557e270a38192554c3126ea5f97434Tim Northover if (MF.getFrameInfo()->hasVarSizedObjects()) { 30872062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t StaticFrameBase; 30972062f5744557e270a38192554c3126ea5f97434Tim Northover StaticFrameBase = -(NumInitialBytes + FuncInfo->getFramePointerOffset()); 31072062f5744557e270a38192554c3126ea5f97434Tim Northover emitRegUpdate(MBB, FirstEpilogue, DL, TII, 31172062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64::XSP, AArch64::X29, AArch64::NoRegister, 31272062f5744557e270a38192554c3126ea5f97434Tim Northover StaticFrameBase); 31372062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 31472062f5744557e270a38192554c3126ea5f97434Tim Northover emitSPUpdate(MBB, FirstEpilogue, DL,TII, AArch64::X16, NumResidualBytes); 31572062f5744557e270a38192554c3126ea5f97434Tim Northover } 31672062f5744557e270a38192554c3126ea5f97434Tim Northover} 31772062f5744557e270a38192554c3126ea5f97434Tim Northover 31872062f5744557e270a38192554c3126ea5f97434Tim Northoverint64_t 31972062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::resolveFrameIndexReference(MachineFunction &MF, 32072062f5744557e270a38192554c3126ea5f97434Tim Northover int FrameIndex, 32172062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned &FrameReg, 32272062f5744557e270a38192554c3126ea5f97434Tim Northover int SPAdj, 32372062f5744557e270a38192554c3126ea5f97434Tim Northover bool IsCalleeSaveOp) const { 32472062f5744557e270a38192554c3126ea5f97434Tim Northover AArch64MachineFunctionInfo *FuncInfo = 32572062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getInfo<AArch64MachineFunctionInfo>(); 32672062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo *MFI = MF.getFrameInfo(); 32772062f5744557e270a38192554c3126ea5f97434Tim Northover 32872062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t TopOfFrameOffset = MFI->getObjectOffset(FrameIndex); 32972062f5744557e270a38192554c3126ea5f97434Tim Northover 33072062f5744557e270a38192554c3126ea5f97434Tim Northover assert(!(IsCalleeSaveOp && FuncInfo->getInitialStackAdjust() == 0) 33172062f5744557e270a38192554c3126ea5f97434Tim Northover && "callee-saved register in unexpected place"); 33272062f5744557e270a38192554c3126ea5f97434Tim Northover 33372062f5744557e270a38192554c3126ea5f97434Tim Northover // If the frame for this function is particularly large, we adjust the stack 33472062f5744557e270a38192554c3126ea5f97434Tim Northover // in two phases which means the callee-save related operations see a 33572062f5744557e270a38192554c3126ea5f97434Tim Northover // different (intermediate) stack size. 33672062f5744557e270a38192554c3126ea5f97434Tim Northover int64_t FrameRegPos; 33772062f5744557e270a38192554c3126ea5f97434Tim Northover if (IsCalleeSaveOp) { 33872062f5744557e270a38192554c3126ea5f97434Tim Northover FrameReg = AArch64::XSP; 33972062f5744557e270a38192554c3126ea5f97434Tim Northover FrameRegPos = -static_cast<int64_t>(FuncInfo->getInitialStackAdjust()); 34072062f5744557e270a38192554c3126ea5f97434Tim Northover } else if (useFPForAddressing(MF)) { 34172062f5744557e270a38192554c3126ea5f97434Tim Northover // Have to use the frame pointer since we have no idea where SP is. 34272062f5744557e270a38192554c3126ea5f97434Tim Northover FrameReg = AArch64::X29; 34372062f5744557e270a38192554c3126ea5f97434Tim Northover FrameRegPos = FuncInfo->getFramePointerOffset(); 34472062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 34572062f5744557e270a38192554c3126ea5f97434Tim Northover FrameReg = AArch64::XSP; 34672062f5744557e270a38192554c3126ea5f97434Tim Northover FrameRegPos = -static_cast<int64_t>(MFI->getStackSize()) + SPAdj; 34772062f5744557e270a38192554c3126ea5f97434Tim Northover } 34872062f5744557e270a38192554c3126ea5f97434Tim Northover 34972062f5744557e270a38192554c3126ea5f97434Tim Northover return TopOfFrameOffset - FrameRegPos; 35072062f5744557e270a38192554c3126ea5f97434Tim Northover} 35172062f5744557e270a38192554c3126ea5f97434Tim Northover 35272062f5744557e270a38192554c3126ea5f97434Tim Northovervoid 35372062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, 35472062f5744557e270a38192554c3126ea5f97434Tim Northover RegScavenger *RS) const { 35572062f5744557e270a38192554c3126ea5f97434Tim Northover const AArch64RegisterInfo *RegInfo = 35672062f5744557e270a38192554c3126ea5f97434Tim Northover static_cast<const AArch64RegisterInfo *>(MF.getTarget().getRegisterInfo()); 35772062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo *MFI = MF.getFrameInfo(); 35872062f5744557e270a38192554c3126ea5f97434Tim Northover const AArch64InstrInfo &TII = 35972062f5744557e270a38192554c3126ea5f97434Tim Northover *static_cast<const AArch64InstrInfo *>(MF.getTarget().getInstrInfo()); 36072062f5744557e270a38192554c3126ea5f97434Tim Northover 36172062f5744557e270a38192554c3126ea5f97434Tim Northover if (hasFP(MF)) { 36272062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getRegInfo().setPhysRegUsed(AArch64::X29); 36372062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getRegInfo().setPhysRegUsed(AArch64::X30); 36472062f5744557e270a38192554c3126ea5f97434Tim Northover } 36572062f5744557e270a38192554c3126ea5f97434Tim Northover 36672062f5744557e270a38192554c3126ea5f97434Tim Northover // If addressing of local variables is going to be more complicated than 36772062f5744557e270a38192554c3126ea5f97434Tim Northover // shoving a base register and an offset into the instruction then we may well 36872062f5744557e270a38192554c3126ea5f97434Tim Northover // need to scavenge registers. We should either specifically add an 36972062f5744557e270a38192554c3126ea5f97434Tim Northover // callee-save register for this purpose or allocate an extra spill slot. 37072062f5744557e270a38192554c3126ea5f97434Tim Northover 37172062f5744557e270a38192554c3126ea5f97434Tim Northover bool BigStack = 3720cc52c67dbc2e073e3f7f34e05e3e7cd17ba9745Hal Finkel (RS && 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 { 39572062f5744557e270a38192554c3126ea5f97434Tim Northover // Create a stack slot for scavenging purposes. PrologEpilogInserter 39672062f5744557e270a38192554c3126ea5f97434Tim Northover // helpfully places it near either SP or FP for us to avoid 39772062f5744557e270a38192554c3126ea5f97434Tim Northover // infinitely-regression during scavenging. 39872062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterClass *RC = &AArch64::GPR64RegClass; 39972062f5744557e270a38192554c3126ea5f97434Tim Northover RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(), 40072062f5744557e270a38192554c3126ea5f97434Tim Northover RC->getAlignment(), 40172062f5744557e270a38192554c3126ea5f97434Tim Northover false)); 40272062f5744557e270a38192554c3126ea5f97434Tim Northover } 40372062f5744557e270a38192554c3126ea5f97434Tim Northover} 40472062f5744557e270a38192554c3126ea5f97434Tim Northover 40572062f5744557e270a38192554c3126ea5f97434Tim Northoverbool AArch64FrameLowering::determinePrologueDeath(MachineBasicBlock &MBB, 40672062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned Reg) const { 40772062f5744557e270a38192554c3126ea5f97434Tim Northover // If @llvm.returnaddress is called then it will refer to X30 by some means; 40872062f5744557e270a38192554c3126ea5f97434Tim Northover // the prologue store does not kill the register. 40972062f5744557e270a38192554c3126ea5f97434Tim Northover if (Reg == AArch64::X30) { 41072062f5744557e270a38192554c3126ea5f97434Tim Northover if (MBB.getParent()->getFrameInfo()->isReturnAddressTaken() 41172062f5744557e270a38192554c3126ea5f97434Tim Northover && MBB.getParent()->getRegInfo().isLiveIn(Reg)) 41272062f5744557e270a38192554c3126ea5f97434Tim Northover return false; 41372062f5744557e270a38192554c3126ea5f97434Tim Northover } 41472062f5744557e270a38192554c3126ea5f97434Tim Northover 41572062f5744557e270a38192554c3126ea5f97434Tim Northover // In all other cases, physical registers are dead after they've been saved 41672062f5744557e270a38192554c3126ea5f97434Tim Northover // but live at the beginning of the prologue block. 41772062f5744557e270a38192554c3126ea5f97434Tim Northover MBB.addLiveIn(Reg); 41872062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 41972062f5744557e270a38192554c3126ea5f97434Tim Northover} 42072062f5744557e270a38192554c3126ea5f97434Tim Northover 42172062f5744557e270a38192554c3126ea5f97434Tim Northovervoid 42272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::emitFrameMemOps(bool isPrologue, MachineBasicBlock &MBB, 42372062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI, 42472062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI, 42572062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *TRI, 42672062f5744557e270a38192554c3126ea5f97434Tim Northover LoadStoreMethod PossClasses[], 42772062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned NumClasses) const { 42872062f5744557e270a38192554c3126ea5f97434Tim Northover DebugLoc DL = MBB.findDebugLoc(MBBI); 42972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFunction &MF = *MBB.getParent(); 43072062f5744557e270a38192554c3126ea5f97434Tim Northover MachineFrameInfo &MFI = *MF.getFrameInfo(); 43172062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 43272062f5744557e270a38192554c3126ea5f97434Tim Northover 43372062f5744557e270a38192554c3126ea5f97434Tim Northover // A certain amount of implicit contract is present here. The actual stack 43472062f5744557e270a38192554c3126ea5f97434Tim Northover // offsets haven't been allocated officially yet, so for strictly correct code 43572062f5744557e270a38192554c3126ea5f97434Tim Northover // we rely on the fact that the elements of CSI are allocated in order 43672062f5744557e270a38192554c3126ea5f97434Tim Northover // starting at SP, purely as dictated by size and alignment. In practice since 43772062f5744557e270a38192554c3126ea5f97434Tim Northover // this function handles the only accesses to those slots it's not quite so 43872062f5744557e270a38192554c3126ea5f97434Tim Northover // important. 43972062f5744557e270a38192554c3126ea5f97434Tim Northover // 44072062f5744557e270a38192554c3126ea5f97434Tim Northover // We have also ordered the Callee-saved register list in AArch64CallingConv 44172062f5744557e270a38192554c3126ea5f97434Tim Northover // so that the above scheme puts registers in order: in particular we want 44272062f5744557e270a38192554c3126ea5f97434Tim Northover // &X30 to be &X29+8 for an ABI-correct frame record (PCS 5.2.2) 44372062f5744557e270a38192554c3126ea5f97434Tim Northover for (unsigned i = 0, e = CSI.size(); i < e; ++i) { 44472062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned Reg = CSI[i].getReg(); 44572062f5744557e270a38192554c3126ea5f97434Tim Northover 44672062f5744557e270a38192554c3126ea5f97434Tim Northover // First we need to find out which register class the register belongs to so 44772062f5744557e270a38192554c3126ea5f97434Tim Northover // that we can use the correct load/store instrucitons. 44872062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned ClassIdx; 44972062f5744557e270a38192554c3126ea5f97434Tim Northover for (ClassIdx = 0; ClassIdx < NumClasses; ++ClassIdx) { 45072062f5744557e270a38192554c3126ea5f97434Tim Northover if (PossClasses[ClassIdx].RegClass->contains(Reg)) 45172062f5744557e270a38192554c3126ea5f97434Tim Northover break; 45272062f5744557e270a38192554c3126ea5f97434Tim Northover } 45372062f5744557e270a38192554c3126ea5f97434Tim Northover assert(ClassIdx != NumClasses 45472062f5744557e270a38192554c3126ea5f97434Tim Northover && "Asked to store register in unexpected class"); 45572062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterClass &TheClass = *PossClasses[ClassIdx].RegClass; 45672062f5744557e270a38192554c3126ea5f97434Tim Northover 45772062f5744557e270a38192554c3126ea5f97434Tim Northover // Now we need to decide whether it's possible to emit a paired instruction: 45872062f5744557e270a38192554c3126ea5f97434Tim Northover // for this we want the next register to be in the same class. 45972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineInstrBuilder NewMI; 46072062f5744557e270a38192554c3126ea5f97434Tim Northover bool Pair = false; 46172062f5744557e270a38192554c3126ea5f97434Tim Northover if (i + 1 < CSI.size() && TheClass.contains(CSI[i+1].getReg())) { 46272062f5744557e270a38192554c3126ea5f97434Tim Northover Pair = true; 46372062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned StLow = 0, StHigh = 0; 46472062f5744557e270a38192554c3126ea5f97434Tim Northover if (isPrologue) { 46572062f5744557e270a38192554c3126ea5f97434Tim Northover // Most of these registers will be live-in to the MBB and killed by our 46672062f5744557e270a38192554c3126ea5f97434Tim Northover // store, though there are exceptions (see determinePrologueDeath). 46772062f5744557e270a38192554c3126ea5f97434Tim Northover StLow = getKillRegState(determinePrologueDeath(MBB, CSI[i+1].getReg())); 46872062f5744557e270a38192554c3126ea5f97434Tim Northover StHigh = getKillRegState(determinePrologueDeath(MBB, CSI[i].getReg())); 46972062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 47072062f5744557e270a38192554c3126ea5f97434Tim Northover StLow = RegState::Define; 47172062f5744557e270a38192554c3126ea5f97434Tim Northover StHigh = RegState::Define; 47272062f5744557e270a38192554c3126ea5f97434Tim Northover } 47372062f5744557e270a38192554c3126ea5f97434Tim Northover 47472062f5744557e270a38192554c3126ea5f97434Tim Northover NewMI = BuildMI(MBB, MBBI, DL, TII.get(PossClasses[ClassIdx].PairOpcode)) 47572062f5744557e270a38192554c3126ea5f97434Tim Northover .addReg(CSI[i+1].getReg(), StLow) 47672062f5744557e270a38192554c3126ea5f97434Tim Northover .addReg(CSI[i].getReg(), StHigh); 47772062f5744557e270a38192554c3126ea5f97434Tim Northover 47872062f5744557e270a38192554c3126ea5f97434Tim Northover // If it's a paired op, we've consumed two registers 47972062f5744557e270a38192554c3126ea5f97434Tim Northover ++i; 48072062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 48172062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned State; 48272062f5744557e270a38192554c3126ea5f97434Tim Northover if (isPrologue) { 48372062f5744557e270a38192554c3126ea5f97434Tim Northover State = getKillRegState(determinePrologueDeath(MBB, CSI[i].getReg())); 48472062f5744557e270a38192554c3126ea5f97434Tim Northover } else { 48572062f5744557e270a38192554c3126ea5f97434Tim Northover State = RegState::Define; 48672062f5744557e270a38192554c3126ea5f97434Tim Northover } 48772062f5744557e270a38192554c3126ea5f97434Tim Northover 488dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover NewMI = BuildMI(MBB, MBBI, DL, 489dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover TII.get(PossClasses[ClassIdx].SingleOpcode)) 49072062f5744557e270a38192554c3126ea5f97434Tim Northover .addReg(CSI[i].getReg(), State); 49172062f5744557e270a38192554c3126ea5f97434Tim Northover } 49272062f5744557e270a38192554c3126ea5f97434Tim Northover 49372062f5744557e270a38192554c3126ea5f97434Tim Northover // Note that the FrameIdx refers to the second register in a pair: it will 49472062f5744557e270a38192554c3126ea5f97434Tim Northover // be allocated the smaller numeric address and so is the one an LDP/STP 49572062f5744557e270a38192554c3126ea5f97434Tim Northover // address must use. 49672062f5744557e270a38192554c3126ea5f97434Tim Northover int FrameIdx = CSI[i].getFrameIdx(); 49772062f5744557e270a38192554c3126ea5f97434Tim Northover MachineMemOperand::MemOperandFlags Flags; 49872062f5744557e270a38192554c3126ea5f97434Tim Northover Flags = isPrologue ? MachineMemOperand::MOStore : MachineMemOperand::MOLoad; 49972062f5744557e270a38192554c3126ea5f97434Tim Northover MachineMemOperand *MMO = 50072062f5744557e270a38192554c3126ea5f97434Tim Northover MF.getMachineMemOperand(MachinePointerInfo::getFixedStack(FrameIdx), 501dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover Flags, 502dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover Pair ? TheClass.getSize() * 2 : TheClass.getSize(), 503dfe076af9879eb68a7b8331f9c02eecf563d85beTim Northover MFI.getObjectAlignment(FrameIdx)); 50472062f5744557e270a38192554c3126ea5f97434Tim Northover 50572062f5744557e270a38192554c3126ea5f97434Tim Northover NewMI.addFrameIndex(FrameIdx) 50672062f5744557e270a38192554c3126ea5f97434Tim Northover .addImm(0) // address-register offset 50772062f5744557e270a38192554c3126ea5f97434Tim Northover .addMemOperand(MMO); 50872062f5744557e270a38192554c3126ea5f97434Tim Northover 50972062f5744557e270a38192554c3126ea5f97434Tim Northover if (isPrologue) 51072062f5744557e270a38192554c3126ea5f97434Tim Northover NewMI.setMIFlags(MachineInstr::FrameSetup); 51172062f5744557e270a38192554c3126ea5f97434Tim Northover 51272062f5744557e270a38192554c3126ea5f97434Tim Northover // For aesthetic reasons, during an epilogue we want to emit complementary 51372062f5744557e270a38192554c3126ea5f97434Tim Northover // operations to the prologue, but in the opposite order. So we still 51472062f5744557e270a38192554c3126ea5f97434Tim Northover // iterate through the CalleeSavedInfo list in order, but we put the 51572062f5744557e270a38192554c3126ea5f97434Tim Northover // instructions successively earlier in the MBB. 51672062f5744557e270a38192554c3126ea5f97434Tim Northover if (!isPrologue) 51772062f5744557e270a38192554c3126ea5f97434Tim Northover --MBBI; 51872062f5744557e270a38192554c3126ea5f97434Tim Northover } 51972062f5744557e270a38192554c3126ea5f97434Tim Northover} 52072062f5744557e270a38192554c3126ea5f97434Tim Northover 52172062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 52272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 52372062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI, 52472062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI, 52572062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *TRI) const { 52672062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.empty()) 52772062f5744557e270a38192554c3126ea5f97434Tim Northover return false; 52872062f5744557e270a38192554c3126ea5f97434Tim Northover 52972062f5744557e270a38192554c3126ea5f97434Tim Northover static LoadStoreMethod PossibleClasses[] = { 53072062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::GPR64RegClass, AArch64::LSPair64_STR, AArch64::LS64_STR}, 53172062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::FPR64RegClass, AArch64::LSFPPair64_STR, AArch64::LSFP64_STR}, 53272062f5744557e270a38192554c3126ea5f97434Tim Northover }; 53372062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned NumClasses = llvm::array_lengthof(PossibleClasses); 53472062f5744557e270a38192554c3126ea5f97434Tim Northover 53572062f5744557e270a38192554c3126ea5f97434Tim Northover emitFrameMemOps(/* isPrologue = */ true, MBB, MBBI, CSI, TRI, 53672062f5744557e270a38192554c3126ea5f97434Tim Northover PossibleClasses, NumClasses); 53772062f5744557e270a38192554c3126ea5f97434Tim Northover 53872062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 53972062f5744557e270a38192554c3126ea5f97434Tim Northover} 54072062f5744557e270a38192554c3126ea5f97434Tim Northover 54172062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 54272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 54372062f5744557e270a38192554c3126ea5f97434Tim Northover MachineBasicBlock::iterator MBBI, 54472062f5744557e270a38192554c3126ea5f97434Tim Northover const std::vector<CalleeSavedInfo> &CSI, 54572062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *TRI) const { 54672062f5744557e270a38192554c3126ea5f97434Tim Northover 54772062f5744557e270a38192554c3126ea5f97434Tim Northover if (CSI.empty()) 54872062f5744557e270a38192554c3126ea5f97434Tim Northover return false; 54972062f5744557e270a38192554c3126ea5f97434Tim Northover 55072062f5744557e270a38192554c3126ea5f97434Tim Northover static LoadStoreMethod PossibleClasses[] = { 55172062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::GPR64RegClass, AArch64::LSPair64_LDR, AArch64::LS64_LDR}, 55272062f5744557e270a38192554c3126ea5f97434Tim Northover {&AArch64::FPR64RegClass, AArch64::LSFPPair64_LDR, AArch64::LSFP64_LDR}, 55372062f5744557e270a38192554c3126ea5f97434Tim Northover }; 55472062f5744557e270a38192554c3126ea5f97434Tim Northover unsigned NumClasses = llvm::array_lengthof(PossibleClasses); 55572062f5744557e270a38192554c3126ea5f97434Tim Northover 55672062f5744557e270a38192554c3126ea5f97434Tim Northover emitFrameMemOps(/* isPrologue = */ false, MBB, MBBI, CSI, TRI, 55772062f5744557e270a38192554c3126ea5f97434Tim Northover PossibleClasses, NumClasses); 55872062f5744557e270a38192554c3126ea5f97434Tim Northover 55972062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 56072062f5744557e270a38192554c3126ea5f97434Tim Northover} 56172062f5744557e270a38192554c3126ea5f97434Tim Northover 56272062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 56372062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::hasFP(const MachineFunction &MF) const { 56472062f5744557e270a38192554c3126ea5f97434Tim Northover const MachineFrameInfo *MFI = MF.getFrameInfo(); 56572062f5744557e270a38192554c3126ea5f97434Tim Northover const TargetRegisterInfo *RI = MF.getTarget().getRegisterInfo(); 56672062f5744557e270a38192554c3126ea5f97434Tim Northover 56772062f5744557e270a38192554c3126ea5f97434Tim Northover // This is a decision of ABI compliance. The AArch64 PCS gives various options 56872062f5744557e270a38192554c3126ea5f97434Tim Northover // for conformance, and even at the most stringent level more or less permits 56972062f5744557e270a38192554c3126ea5f97434Tim Northover // elimination for leaf functions because there's no loss of functionality 57072062f5744557e270a38192554c3126ea5f97434Tim Northover // (for debugging etc).. 57172062f5744557e270a38192554c3126ea5f97434Tim Northover if (MF.getTarget().Options.DisableFramePointerElim(MF) && MFI->hasCalls()) 57272062f5744557e270a38192554c3126ea5f97434Tim Northover return true; 57372062f5744557e270a38192554c3126ea5f97434Tim Northover 57472062f5744557e270a38192554c3126ea5f97434Tim Northover // The following are hard-limits: incorrect code will be generated if we try 57572062f5744557e270a38192554c3126ea5f97434Tim Northover // to omit the frame. 57672062f5744557e270a38192554c3126ea5f97434Tim Northover return (RI->needsStackRealignment(MF) || 57772062f5744557e270a38192554c3126ea5f97434Tim Northover MFI->hasVarSizedObjects() || 57872062f5744557e270a38192554c3126ea5f97434Tim Northover MFI->isFrameAddressTaken()); 57972062f5744557e270a38192554c3126ea5f97434Tim Northover} 58072062f5744557e270a38192554c3126ea5f97434Tim Northover 58172062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 58272062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::useFPForAddressing(const MachineFunction &MF) const { 58372062f5744557e270a38192554c3126ea5f97434Tim Northover return MF.getFrameInfo()->hasVarSizedObjects(); 58472062f5744557e270a38192554c3126ea5f97434Tim Northover} 58572062f5744557e270a38192554c3126ea5f97434Tim Northover 58672062f5744557e270a38192554c3126ea5f97434Tim Northoverbool 58772062f5744557e270a38192554c3126ea5f97434Tim NorthoverAArch64FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 58872062f5744557e270a38192554c3126ea5f97434Tim Northover const MachineFrameInfo *MFI = MF.getFrameInfo(); 58972062f5744557e270a38192554c3126ea5f97434Tim Northover 59072062f5744557e270a38192554c3126ea5f97434Tim Northover // Of the various reasons for having a frame pointer, it's actually only 59172062f5744557e270a38192554c3126ea5f97434Tim Northover // variable-sized objects that prevent reservation of a call frame. 59272062f5744557e270a38192554c3126ea5f97434Tim Northover return !(hasFP(MF) && MFI->hasVarSizedObjects()); 59372062f5744557e270a38192554c3126ea5f97434Tim Northover} 594700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 595700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid 596700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyAArch64FrameLowering::eliminateCallFramePseudoInstr( 597700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineFunction &MF, 598700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock &MBB, 599700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator MI) const { 600700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky const AArch64InstrInfo &TII = 601700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky *static_cast<const AArch64InstrInfo *>(MF.getTarget().getInstrInfo()); 602700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky DebugLoc dl = MI->getDebugLoc(); 603700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky int Opcode = MI->getOpcode(); 604700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode(); 605700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t CalleePopAmount = IsDestroy ? MI->getOperand(1).getImm() : 0; 606700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 607700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (!hasReservedCallFrame(MF)) { 608700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned Align = getStackAlignment(); 609700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 610700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky int64_t Amount = MI->getOperand(0).getImm(); 611700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount = RoundUpToAlignment(Amount, Align); 612700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (!IsDestroy) Amount = -Amount; 613700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 614700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it 615700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // doesn't have to pop anything), then the first operand will be zero too so 616700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // this adjustment is a no-op. 617700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (CalleePopAmount == 0) { 618700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // FIXME: in-function stack adjustment for calls is limited to 12-bits 619700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // because there's no guaranteed temporary register available. Mostly call 620700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // frames will be allocated at the start of a function so this is OK, but 621700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // it is a limitation that needs dealing with. 622700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky assert(Amount > -0xfff && Amount < 0xfff && "call frame too large"); 623700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, Amount); 624700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 625700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else if (CalleePopAmount != 0) { 626700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If the calling convention demands that the callee pops arguments from the 627700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // stack, we want to add it back if we have a reserved call frame. 628700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky assert(CalleePopAmount < 0xfff && "call frame too large"); 629700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, -CalleePopAmount); 630700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 631700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 632700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.erase(MI); 633700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 634