1235633Sdim//===-- Thumb1FrameLowering.cpp - Thumb1 Frame Information ----------------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file contains the Thumb1 implementation of TargetFrameLowering class. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14218885Sdim#include "Thumb1FrameLowering.h" 15218885Sdim#include "ARMMachineFunctionInfo.h" 16218885Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 17218885Sdim#include "llvm/CodeGen/MachineFunction.h" 18218885Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 19218885Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 20218885Sdim 21218885Sdimusing namespace llvm; 22218885Sdim 23226890Sdimbool Thumb1FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const{ 24218885Sdim const MachineFrameInfo *FFI = MF.getFrameInfo(); 25218885Sdim unsigned CFSize = FFI->getMaxCallFrameSize(); 26218885Sdim // It's not always a good idea to include the call frame as part of the 27218885Sdim // stack frame. ARM (especially Thumb) has small immediate offset to 28218885Sdim // address the stack frame. So a large call frame can cause poor codegen 29218885Sdim // and may even makes it impossible to scavenge a register. 30218885Sdim if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4 31218885Sdim return false; 32218885Sdim 33218885Sdim return !MF.getFrameInfo()->hasVarSizedObjects(); 34218885Sdim} 35218885Sdim 36221345Sdimstatic void 37221345SdimemitSPUpdate(MachineBasicBlock &MBB, 38221345Sdim MachineBasicBlock::iterator &MBBI, 39221345Sdim const TargetInstrInfo &TII, DebugLoc dl, 40221345Sdim const Thumb1RegisterInfo &MRI, 41221345Sdim int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) { 42221345Sdim emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII, 43221345Sdim MRI, MIFlags); 44218885Sdim} 45218885Sdim 46252723Sdim 47252723Sdimvoid Thumb1FrameLowering:: 48252723SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 49252723Sdim MachineBasicBlock::iterator I) const { 50252723Sdim const Thumb1InstrInfo &TII = 51252723Sdim *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo()); 52252723Sdim const Thumb1RegisterInfo *RegInfo = 53252723Sdim static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo()); 54252723Sdim if (!hasReservedCallFrame(MF)) { 55252723Sdim // If we have alloca, convert as follows: 56252723Sdim // ADJCALLSTACKDOWN -> sub, sp, sp, amount 57252723Sdim // ADJCALLSTACKUP -> add, sp, sp, amount 58252723Sdim MachineInstr *Old = I; 59252723Sdim DebugLoc dl = Old->getDebugLoc(); 60252723Sdim unsigned Amount = Old->getOperand(0).getImm(); 61252723Sdim if (Amount != 0) { 62252723Sdim // We need to keep the stack aligned properly. To do this, we round the 63252723Sdim // amount of space needed for the outgoing arguments up to the next 64252723Sdim // alignment boundary. 65252723Sdim unsigned Align = getStackAlignment(); 66252723Sdim Amount = (Amount+Align-1)/Align*Align; 67252723Sdim 68252723Sdim // Replace the pseudo instruction with a new instruction... 69252723Sdim unsigned Opc = Old->getOpcode(); 70252723Sdim if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) { 71252723Sdim emitSPUpdate(MBB, I, TII, dl, *RegInfo, -Amount); 72252723Sdim } else { 73252723Sdim assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP); 74252723Sdim emitSPUpdate(MBB, I, TII, dl, *RegInfo, Amount); 75252723Sdim } 76252723Sdim } 77252723Sdim } 78252723Sdim MBB.erase(I); 79252723Sdim} 80252723Sdim 81218885Sdimvoid Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const { 82218885Sdim MachineBasicBlock &MBB = MF.front(); 83218885Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 84218885Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 85218885Sdim ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 86218885Sdim const Thumb1RegisterInfo *RegInfo = 87218885Sdim static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo()); 88218885Sdim const Thumb1InstrInfo &TII = 89218885Sdim *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo()); 90218885Sdim 91263509Sdim unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment(); 92263509Sdim unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align); 93218885Sdim unsigned NumBytes = MFI->getStackSize(); 94218885Sdim const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo(); 95218885Sdim DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 96218885Sdim unsigned FramePtr = RegInfo->getFrameRegister(MF); 97218885Sdim unsigned BasePtr = RegInfo->getBaseRegister(); 98218885Sdim 99218885Sdim // Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4. 100218885Sdim NumBytes = (NumBytes + 3) & ~3; 101218885Sdim MFI->setStackSize(NumBytes); 102218885Sdim 103218885Sdim // Determine the sizes of each callee-save spill areas and record which frame 104218885Sdim // belongs to which callee-save spill areas. 105218885Sdim unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0; 106218885Sdim int FramePtrSpillFI = 0; 107218885Sdim 108252723Sdim if (ArgRegsSaveSize) 109252723Sdim emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -ArgRegsSaveSize, 110221345Sdim MachineInstr::FrameSetup); 111218885Sdim 112218885Sdim if (!AFI->hasStackFrame()) { 113218885Sdim if (NumBytes != 0) 114221345Sdim emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes, 115221345Sdim MachineInstr::FrameSetup); 116218885Sdim return; 117218885Sdim } 118218885Sdim 119218885Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) { 120218885Sdim unsigned Reg = CSI[i].getReg(); 121218885Sdim int FI = CSI[i].getFrameIdx(); 122218885Sdim switch (Reg) { 123218885Sdim case ARM::R4: 124218885Sdim case ARM::R5: 125218885Sdim case ARM::R6: 126218885Sdim case ARM::R7: 127218885Sdim case ARM::LR: 128218885Sdim if (Reg == FramePtr) 129218885Sdim FramePtrSpillFI = FI; 130218885Sdim GPRCS1Size += 4; 131218885Sdim break; 132218885Sdim case ARM::R8: 133218885Sdim case ARM::R9: 134218885Sdim case ARM::R10: 135218885Sdim case ARM::R11: 136218885Sdim if (Reg == FramePtr) 137218885Sdim FramePtrSpillFI = FI; 138263509Sdim if (STI.isTargetIOS()) 139218885Sdim GPRCS2Size += 4; 140263509Sdim else 141218885Sdim GPRCS1Size += 4; 142218885Sdim break; 143218885Sdim default: 144218885Sdim DPRCSSize += 8; 145218885Sdim } 146218885Sdim } 147218885Sdim 148218885Sdim if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) { 149218885Sdim ++MBBI; 150218885Sdim if (MBBI != MBB.end()) 151218885Sdim dl = MBBI->getDebugLoc(); 152218885Sdim } 153218885Sdim 154218885Sdim // Determine starting offsets of spill areas. 155218885Sdim unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize); 156218885Sdim unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize; 157218885Sdim unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size; 158252723Sdim bool HasFP = hasFP(MF); 159252723Sdim if (HasFP) 160252723Sdim AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + 161252723Sdim NumBytes); 162218885Sdim AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset); 163218885Sdim AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset); 164218885Sdim AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset); 165218885Sdim NumBytes = DPRCSOffset; 166218885Sdim 167263509Sdim int FramePtrOffsetInBlock = 0; 168263509Sdim if (tryFoldSPUpdateIntoPushPop(MF, prior(MBBI), NumBytes)) { 169263509Sdim FramePtrOffsetInBlock = NumBytes; 170263509Sdim NumBytes = 0; 171263509Sdim } 172263509Sdim 173218885Sdim // Adjust FP so it point to the stack slot that contains the previous FP. 174252723Sdim if (HasFP) { 175263509Sdim FramePtrOffsetInBlock += MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size; 176226890Sdim AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr) 177263509Sdim .addReg(ARM::SP).addImm(FramePtrOffsetInBlock / 4) 178226890Sdim .setMIFlags(MachineInstr::FrameSetup)); 179224145Sdim if (NumBytes > 508) 180224145Sdim // If offset is > 508 then sp cannot be adjusted in a single instruction, 181218885Sdim // try restoring from fp instead. 182218885Sdim AFI->setShouldRestoreSPFromFP(true); 183218885Sdim } 184218885Sdim 185218885Sdim if (NumBytes) 186218885Sdim // Insert it after all the callee-save spills. 187221345Sdim emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, -NumBytes, 188221345Sdim MachineInstr::FrameSetup); 189218885Sdim 190252723Sdim if (STI.isTargetELF() && HasFP) 191218885Sdim MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() - 192218885Sdim AFI->getFramePtrSpillOffset()); 193218885Sdim 194218885Sdim AFI->setGPRCalleeSavedArea1Size(GPRCS1Size); 195218885Sdim AFI->setGPRCalleeSavedArea2Size(GPRCS2Size); 196218885Sdim AFI->setDPRCalleeSavedAreaSize(DPRCSSize); 197218885Sdim 198226890Sdim // Thumb1 does not currently support dynamic stack realignment. Report a 199226890Sdim // fatal error rather then silently generate bad code. 200226890Sdim if (RegInfo->needsStackRealignment(MF)) 201226890Sdim report_fatal_error("Dynamic stack realignment not supported for thumb1."); 202226890Sdim 203218885Sdim // If we need a base pointer, set it up here. It's whatever the value 204218885Sdim // of the stack pointer is at this point. Any variable size objects 205218885Sdim // will be allocated after this, so we can still use the base pointer 206218885Sdim // to reference locals. 207218885Sdim if (RegInfo->hasBasePointer(MF)) 208224145Sdim AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), BasePtr) 209224145Sdim .addReg(ARM::SP)); 210221345Sdim 211218885Sdim // If the frame has variable sized objects then the epilogue must restore 212218885Sdim // the sp from fp. We can assume there's an FP here since hasFP already 213218885Sdim // checks for hasVarSizedObjects. 214218885Sdim if (MFI->hasVarSizedObjects()) 215218885Sdim AFI->setShouldRestoreSPFromFP(true); 216218885Sdim} 217218885Sdim 218235633Sdimstatic bool isCSRestore(MachineInstr *MI, const uint16_t *CSRegs) { 219224145Sdim if (MI->getOpcode() == ARM::tLDRspi && 220218885Sdim MI->getOperand(1).isFI() && 221218885Sdim isCalleeSavedRegister(MI->getOperand(0).getReg(), CSRegs)) 222218885Sdim return true; 223218885Sdim else if (MI->getOpcode() == ARM::tPOP) { 224218885Sdim // The first two operands are predicates. The last two are 225218885Sdim // imp-def and imp-use of SP. Check everything in between. 226218885Sdim for (int i = 2, e = MI->getNumOperands() - 2; i != e; ++i) 227218885Sdim if (!isCalleeSavedRegister(MI->getOperand(i).getReg(), CSRegs)) 228218885Sdim return false; 229218885Sdim return true; 230218885Sdim } 231218885Sdim return false; 232218885Sdim} 233218885Sdim 234218885Sdimvoid Thumb1FrameLowering::emitEpilogue(MachineFunction &MF, 235218885Sdim MachineBasicBlock &MBB) const { 236218885Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 237218885Sdim assert((MBBI->getOpcode() == ARM::tBX_RET || 238218885Sdim MBBI->getOpcode() == ARM::tPOP_RET) && 239218885Sdim "Can only insert epilog into returning blocks"); 240218885Sdim DebugLoc dl = MBBI->getDebugLoc(); 241218885Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 242218885Sdim ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 243218885Sdim const Thumb1RegisterInfo *RegInfo = 244218885Sdim static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo()); 245218885Sdim const Thumb1InstrInfo &TII = 246218885Sdim *static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo()); 247218885Sdim 248263509Sdim unsigned Align = MF.getTarget().getFrameLowering()->getStackAlignment(); 249263509Sdim unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize(Align); 250218885Sdim int NumBytes = (int)MFI->getStackSize(); 251235633Sdim const uint16_t *CSRegs = RegInfo->getCalleeSavedRegs(); 252218885Sdim unsigned FramePtr = RegInfo->getFrameRegister(MF); 253218885Sdim 254218885Sdim if (!AFI->hasStackFrame()) { 255218885Sdim if (NumBytes != 0) 256218885Sdim emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes); 257218885Sdim } else { 258218885Sdim // Unwind MBBI to point to first LDR / VLDRD. 259218885Sdim if (MBBI != MBB.begin()) { 260218885Sdim do 261218885Sdim --MBBI; 262218885Sdim while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs)); 263218885Sdim if (!isCSRestore(MBBI, CSRegs)) 264218885Sdim ++MBBI; 265218885Sdim } 266218885Sdim 267218885Sdim // Move SP to start of FP callee save spill area. 268218885Sdim NumBytes -= (AFI->getGPRCalleeSavedArea1Size() + 269218885Sdim AFI->getGPRCalleeSavedArea2Size() + 270218885Sdim AFI->getDPRCalleeSavedAreaSize()); 271218885Sdim 272218885Sdim if (AFI->shouldRestoreSPFromFP()) { 273218885Sdim NumBytes = AFI->getFramePtrSpillOffset() - NumBytes; 274218885Sdim // Reset SP based on frame pointer only if the stack frame extends beyond 275218885Sdim // frame pointer stack slot, the target is ELF and the function has FP, or 276218885Sdim // the target uses var sized objects. 277218885Sdim if (NumBytes) { 278218885Sdim assert(MF.getRegInfo().isPhysRegUsed(ARM::R4) && 279218885Sdim "No scratch register to restore SP from FP!"); 280221345Sdim emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::R4, FramePtr, -NumBytes, 281221345Sdim TII, *RegInfo); 282224145Sdim AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), 283224145Sdim ARM::SP) 284224145Sdim .addReg(ARM::R4)); 285218885Sdim } else 286224145Sdim AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), 287224145Sdim ARM::SP) 288224145Sdim .addReg(FramePtr)); 289218885Sdim } else { 290218885Sdim if (MBBI->getOpcode() == ARM::tBX_RET && 291218885Sdim &MBB.front() != MBBI && 292218885Sdim prior(MBBI)->getOpcode() == ARM::tPOP) { 293218885Sdim MachineBasicBlock::iterator PMBBI = prior(MBBI); 294263509Sdim if (!tryFoldSPUpdateIntoPushPop(MF, PMBBI, NumBytes)) 295263509Sdim emitSPUpdate(MBB, PMBBI, TII, dl, *RegInfo, NumBytes); 296263509Sdim } else if (!tryFoldSPUpdateIntoPushPop(MF, MBBI, NumBytes)) 297218885Sdim emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, NumBytes); 298218885Sdim } 299218885Sdim } 300218885Sdim 301252723Sdim if (ArgRegsSaveSize) { 302218885Sdim // Unlike T2 and ARM mode, the T1 pop instruction cannot restore 303218885Sdim // to LR, and we can't pop the value directly to the PC since 304218885Sdim // we need to update the SP after popping the value. Therefore, we 305218885Sdim // pop the old LR into R3 as a temporary. 306218885Sdim 307218885Sdim // Move back past the callee-saved register restoration 308218885Sdim while (MBBI != MBB.end() && isCSRestore(MBBI, CSRegs)) 309218885Sdim ++MBBI; 310218885Sdim // Epilogue for vararg functions: pop LR to R3 and branch off it. 311218885Sdim AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tPOP))) 312218885Sdim .addReg(ARM::R3, RegState::Define); 313218885Sdim 314252723Sdim emitSPUpdate(MBB, MBBI, TII, dl, *RegInfo, ArgRegsSaveSize); 315218885Sdim 316235633Sdim MachineInstrBuilder MIB = 317235633Sdim BuildMI(MBB, MBBI, dl, TII.get(ARM::tBX_RET_vararg)) 318235633Sdim .addReg(ARM::R3, RegState::Kill); 319235633Sdim AddDefaultPred(MIB); 320252723Sdim MIB.copyImplicitOps(&*MBBI); 321218885Sdim // erase the old tBX_RET instruction 322218885Sdim MBB.erase(MBBI); 323218885Sdim } 324218885Sdim} 325218885Sdim 326218885Sdimbool Thumb1FrameLowering:: 327218885SdimspillCalleeSavedRegisters(MachineBasicBlock &MBB, 328218885Sdim MachineBasicBlock::iterator MI, 329218885Sdim const std::vector<CalleeSavedInfo> &CSI, 330218885Sdim const TargetRegisterInfo *TRI) const { 331218885Sdim if (CSI.empty()) 332218885Sdim return false; 333218885Sdim 334218885Sdim DebugLoc DL; 335218885Sdim MachineFunction &MF = *MBB.getParent(); 336218885Sdim const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 337218885Sdim 338218885Sdim if (MI != MBB.end()) DL = MI->getDebugLoc(); 339218885Sdim 340218885Sdim MachineInstrBuilder MIB = BuildMI(MBB, MI, DL, TII.get(ARM::tPUSH)); 341218885Sdim AddDefaultPred(MIB); 342218885Sdim for (unsigned i = CSI.size(); i != 0; --i) { 343218885Sdim unsigned Reg = CSI[i-1].getReg(); 344218885Sdim bool isKill = true; 345218885Sdim 346218885Sdim // Add the callee-saved register as live-in unless it's LR and 347218885Sdim // @llvm.returnaddress is called. If LR is returned for @llvm.returnaddress 348218885Sdim // then it's already added to the function and entry block live-in sets. 349218885Sdim if (Reg == ARM::LR) { 350218885Sdim MachineFunction &MF = *MBB.getParent(); 351218885Sdim if (MF.getFrameInfo()->isReturnAddressTaken() && 352218885Sdim MF.getRegInfo().isLiveIn(Reg)) 353218885Sdim isKill = false; 354218885Sdim } 355218885Sdim 356218885Sdim if (isKill) 357218885Sdim MBB.addLiveIn(Reg); 358218885Sdim 359218885Sdim MIB.addReg(Reg, getKillRegState(isKill)); 360218885Sdim } 361221345Sdim MIB.setMIFlags(MachineInstr::FrameSetup); 362218885Sdim return true; 363218885Sdim} 364218885Sdim 365218885Sdimbool Thumb1FrameLowering:: 366218885SdimrestoreCalleeSavedRegisters(MachineBasicBlock &MBB, 367218885Sdim MachineBasicBlock::iterator MI, 368218885Sdim const std::vector<CalleeSavedInfo> &CSI, 369218885Sdim const TargetRegisterInfo *TRI) const { 370218885Sdim if (CSI.empty()) 371218885Sdim return false; 372218885Sdim 373218885Sdim MachineFunction &MF = *MBB.getParent(); 374218885Sdim ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 375218885Sdim const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 376218885Sdim 377252723Sdim bool isVarArg = AFI->getArgRegsSaveSize() > 0; 378218885Sdim DebugLoc DL = MI->getDebugLoc(); 379218885Sdim MachineInstrBuilder MIB = BuildMI(MF, DL, TII.get(ARM::tPOP)); 380218885Sdim AddDefaultPred(MIB); 381218885Sdim 382218885Sdim bool NumRegs = false; 383218885Sdim for (unsigned i = CSI.size(); i != 0; --i) { 384218885Sdim unsigned Reg = CSI[i-1].getReg(); 385218885Sdim if (Reg == ARM::LR) { 386218885Sdim // Special epilogue for vararg functions. See emitEpilogue 387218885Sdim if (isVarArg) 388218885Sdim continue; 389218885Sdim Reg = ARM::PC; 390218885Sdim (*MIB).setDesc(TII.get(ARM::tPOP_RET)); 391252723Sdim MIB.copyImplicitOps(&*MI); 392218885Sdim MI = MBB.erase(MI); 393218885Sdim } 394218885Sdim MIB.addReg(Reg, getDefRegState(true)); 395218885Sdim NumRegs = true; 396218885Sdim } 397218885Sdim 398218885Sdim // It's illegal to emit pop instruction without operands. 399218885Sdim if (NumRegs) 400218885Sdim MBB.insert(MI, &*MIB); 401218885Sdim else 402218885Sdim MF.DeleteMachineInstr(MIB); 403218885Sdim 404218885Sdim return true; 405218885Sdim} 406