1112758Ssam//===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===// 2112758Ssam// 3112758Ssam// The LLVM Compiler Infrastructure 4112758Ssam// 5112758Ssam// This file is distributed under the University of Illinois Open Source 6112758Ssam// License. See LICENSE.TXT for details. 7112758Ssam// 8112758Ssam//===----------------------------------------------------------------------===// 9112758Ssam// 10112758Ssam// This file contains the MSP430 implementation of TargetFrameLowering class. 11112758Ssam// 12112758Ssam//===----------------------------------------------------------------------===// 13112758Ssam 14112758Ssam#include "MSP430FrameLowering.h" 15112758Ssam#include "MSP430InstrInfo.h" 16112758Ssam#include "MSP430MachineFunctionInfo.h" 17112758Ssam#include "llvm/CodeGen/MachineFrameInfo.h" 18112758Ssam#include "llvm/CodeGen/MachineFunction.h" 19112758Ssam#include "llvm/CodeGen/MachineInstrBuilder.h" 20112758Ssam#include "llvm/CodeGen/MachineModuleInfo.h" 21112758Ssam#include "llvm/CodeGen/MachineRegisterInfo.h" 22112758Ssam#include "llvm/IR/DataLayout.h" 23112758Ssam#include "llvm/IR/Function.h" 24112758Ssam#include "llvm/Support/CommandLine.h" 25112758Ssam#include "llvm/Target/TargetOptions.h" 26112758Ssam 27112758Ssamusing namespace llvm; 28105197Ssam 29105197Ssambool MSP430FrameLowering::hasFP(const MachineFunction &MF) const { 30105197Ssam const MachineFrameInfo *MFI = MF.getFrameInfo(); 31105197Ssam 32105197Ssam return (MF.getTarget().Options.DisableFramePointerElim(MF) || 33105197Ssam MF.getFrameInfo()->hasVarSizedObjects() || 34105197Ssam MFI->isFrameAddressTaken()); 35159965Sthompsa} 36105197Ssam 37105197Ssambool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 38105197Ssam return !MF.getFrameInfo()->hasVarSizedObjects(); 39105197Ssam} 40105197Ssam 41105197Ssamvoid MSP430FrameLowering::emitPrologue(MachineFunction &MF) const { 42105197Ssam MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 43105197Ssam MachineFrameInfo *MFI = MF.getFrameInfo(); 44105197Ssam MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 45105197Ssam const MSP430InstrInfo &TII = 46105197Ssam *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 47257176Sglebius 48171497Sbz MachineBasicBlock::iterator MBBI = MBB.begin(); 49195699Srwatson DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 50105197Ssam 51105197Ssam // Get the number of bytes to allocate from the FrameInfo. 52105197Ssam uint64_t StackSize = MFI->getStackSize(); 53105197Ssam 54105197Ssam uint64_t NumBytes = 0; 55105197Ssam if (hasFP(MF)) { 56105197Ssam // Calculate required stack adjustment 57105197Ssam uint64_t FrameSize = StackSize - 2; 58105197Ssam NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); 59105197Ssam 60105197Ssam // Get the offset of the stack slot for the EBP register... which is 61105197Ssam // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 62105197Ssam // Update the frame offset adjustment. 63105197Ssam MFI->setOffsetAdjustment(-NumBytes); 64281692Sae 65105197Ssam // Save FPW into the appropriate stack slot... 66105197Ssam BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) 67105197Ssam .addReg(MSP430::FPW, RegState::Kill); 68105197Ssam 69105197Ssam // Update FPW with the new base value... 70105197Ssam BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW) 71105197Ssam .addReg(MSP430::SPW); 72105197Ssam 73105197Ssam // Mark the FramePtr as live-in in every block except the entry. 74105197Ssam for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); 75105197Ssam I != E; ++I) 76105197Ssam I->addLiveIn(MSP430::FPW); 77105197Ssam 78105197Ssam } else 79105197Ssam NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); 80105197Ssam 81105197Ssam // Skip the callee-saved push instructions. 82105197Ssam while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r)) 83105197Ssam ++MBBI; 84105197Ssam 85105197Ssam if (MBBI != MBB.end()) 86105197Ssam DL = MBBI->getDebugLoc(); 87194062Svanhu 88194062Svanhu if (NumBytes) { // adjust stack pointer: SPW -= numbytes 89194062Svanhu // If there is an SUB16ri of SPW immediately before this instruction, merge 90194062Svanhu // the two. 91181627Svanhu //NumBytes -= mergeSPUpdates(MBB, MBBI, true); 92181627Svanhu // If there is an ADD16ri or SUB16ri of SPW immediately after this 93181627Svanhu // instruction, merge the two instructions. 94181627Svanhu // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); 95181627Svanhu 96105197Ssam if (NumBytes) { 97105197Ssam MachineInstr *MI = 98105197Ssam BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW) 99105197Ssam .addReg(MSP430::SPW).addImm(NumBytes); 100105197Ssam // The SRW implicit def is dead. 101105197Ssam MI->getOperand(3).setIsDead(); 102105197Ssam } 103105197Ssam } 104105197Ssam} 105120585Ssam 106120585Ssamvoid MSP430FrameLowering::emitEpilogue(MachineFunction &MF, 107282046Sae MachineBasicBlock &MBB) const { 108105197Ssam const MachineFrameInfo *MFI = MF.getFrameInfo(); 109120585Ssam MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 110120585Ssam const MSP430InstrInfo &TII = 111105197Ssam *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 112105197Ssam 113105197Ssam MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 114105197Ssam unsigned RetOpcode = MBBI->getOpcode(); 115105197Ssam DebugLoc DL = MBBI->getDebugLoc(); 116105197Ssam 117105197Ssam switch (RetOpcode) { 118105197Ssam case MSP430::RET: 119105197Ssam case MSP430::RETI: break; // These are ok 120105197Ssam default: 121105197Ssam llvm_unreachable("Can only insert epilog into returning blocks"); 122105197Ssam } 123105197Ssam 124105197Ssam // Get the number of bytes to allocate from the FrameInfo 125105197Ssam uint64_t StackSize = MFI->getStackSize(); 126105197Ssam unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); 127105197Ssam uint64_t NumBytes = 0; 128105197Ssam 129105197Ssam if (hasFP(MF)) { 130105197Ssam // Calculate required stack adjustment 131105197Ssam uint64_t FrameSize = StackSize - 2; 132105197Ssam NumBytes = FrameSize - CSSize; 133105197Ssam 134105197Ssam // pop FPW. 135105197Ssam BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW); 136105197Ssam } else 137120585Ssam NumBytes = StackSize - CSSize; 138105197Ssam 139105197Ssam // Skip the callee-saved pop instructions. 140105197Ssam while (MBBI != MBB.begin()) { 141105197Ssam MachineBasicBlock::iterator PI = prior(MBBI); 142105197Ssam unsigned Opc = PI->getOpcode(); 143105197Ssam if (Opc != MSP430::POP16r && !PI->isTerminator()) 144105197Ssam break; 145105197Ssam --MBBI; 146105197Ssam } 147105197Ssam 148105197Ssam DL = MBBI->getDebugLoc(); 149105197Ssam 150120585Ssam // If there is an ADD16ri or SUB16ri of SPW immediately before this 151105197Ssam // instruction, merge the two instructions. 152105197Ssam //if (NumBytes || MFI->hasVarSizedObjects()) 153105197Ssam // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 154105197Ssam 155105197Ssam if (MFI->hasVarSizedObjects()) { 156105197Ssam BuildMI(MBB, MBBI, DL, 157105197Ssam TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW); 158105197Ssam if (CSSize) { 159105197Ssam MachineInstr *MI = 160105197Ssam BuildMI(MBB, MBBI, DL, 161105197Ssam TII.get(MSP430::SUB16ri), MSP430::SPW) 162105197Ssam .addReg(MSP430::SPW).addImm(CSSize); 163105197Ssam // The SRW implicit def is dead. 164105197Ssam MI->getOperand(3).setIsDead(); 165105197Ssam } 166105197Ssam } else { 167282046Sae // adjust stack pointer back: SPW += numbytes 168282046Sae if (NumBytes) { 169282046Sae MachineInstr *MI = 170282046Sae BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW) 171105197Ssam .addReg(MSP430::SPW).addImm(NumBytes); 172105197Ssam // The SRW implicit def is dead. 173238700Sbz MI->getOperand(3).setIsDead(); 174221129Sbz } 175221129Sbz } 176221129Sbz} 177274467Sae 178282046Sae// FIXME: Can we eleminate these in favour of generic code? 179282046Saebool 180282046SaeMSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 181282046Sae MachineBasicBlock::iterator MI, 182282046Sae const std::vector<CalleeSavedInfo> &CSI, 183221129Sbz const TargetRegisterInfo *TRI) const { 184221129Sbz if (CSI.empty()) 185221129Sbz return false; 186221129Sbz 187221129Sbz DebugLoc DL; 188221129Sbz if (MI != MBB.end()) DL = MI->getDebugLoc(); 189274467Sae 190282046Sae MachineFunction &MF = *MBB.getParent(); 191282046Sae const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 192282046Sae MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>(); 193282046Sae MFI->setCalleeSavedFrameSize(CSI.size() * 2); 194282046Sae 195221129Sbz for (unsigned i = CSI.size(); i != 0; --i) { 196221129Sbz unsigned Reg = CSI[i-1].getReg(); 197221129Sbz // Add the callee-saved register as live-in. It's killed at the spill. 198221129Sbz MBB.addLiveIn(Reg); 199221129Sbz BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r)) 200221129Sbz .addReg(Reg, RegState::Kill); 201221129Sbz } 202221129Sbz return true; 203221129Sbz} 204105197Ssam 205117056Ssambool 206105197SsamMSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 207105197Ssam MachineBasicBlock::iterator MI, 208105197Ssam const std::vector<CalleeSavedInfo> &CSI, 209105197Ssam const TargetRegisterInfo *TRI) const { 210105197Ssam if (CSI.empty()) 211105197Ssam return false; 212105197Ssam 213105197Ssam DebugLoc DL; 214105197Ssam if (MI != MBB.end()) DL = MI->getDebugLoc(); 215194062Svanhu 216194062Svanhu MachineFunction &MF = *MBB.getParent(); 217194062Svanhu const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 218194062Svanhu 219194062Svanhu for (unsigned i = 0, e = CSI.size(); i != e; ++i) 220194062Svanhu BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg()); 221241919Sglebius 222194062Svanhu return true; 223194062Svanhu} 224194062Svanhu 225194062Svanhuvoid MSP430FrameLowering:: 226194062SvanhueliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 227194062Svanhu MachineBasicBlock::iterator I) const { 228194062Svanhu const MSP430InstrInfo &TII = 229194062Svanhu *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 230194062Svanhu unsigned StackAlign = getStackAlignment(); 231194062Svanhu 232194062Svanhu if (!hasReservedCallFrame(MF)) { 233194062Svanhu // If the stack pointer can be changed after prologue, turn the 234194062Svanhu // adjcallstackup instruction into a 'sub SPW, <amt>' and the 235194062Svanhu // adjcallstackdown instruction into 'add SPW, <amt>' 236194062Svanhu // TODO: consider using push / pop instead of sub + store / add 237194062Svanhu MachineInstr *Old = I; 238194062Svanhu uint64_t Amount = Old->getOperand(0).getImm(); 239194062Svanhu if (Amount != 0) { 240194062Svanhu // We need to keep the stack aligned properly. To do this, we round the 241194062Svanhu // amount of space needed for the outgoing arguments up to the next 242194062Svanhu // alignment boundary. 243194062Svanhu Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 244194062Svanhu 245194062Svanhu MachineInstr *New = 0; 246194062Svanhu if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) { 247194062Svanhu New = BuildMI(MF, Old->getDebugLoc(), 248194062Svanhu TII.get(MSP430::SUB16ri), MSP430::SPW) 249194062Svanhu .addReg(MSP430::SPW).addImm(Amount); 250194062Svanhu } else { 251194062Svanhu assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode()); 252194062Svanhu // factor out the amount the callee already popped. 253194062Svanhu uint64_t CalleeAmt = Old->getOperand(1).getImm(); 254194062Svanhu Amount -= CalleeAmt; 255241919Sglebius if (Amount) 256194062Svanhu New = BuildMI(MF, Old->getDebugLoc(), 257194062Svanhu TII.get(MSP430::ADD16ri), MSP430::SPW) 258194062Svanhu .addReg(MSP430::SPW).addImm(Amount); 259194062Svanhu } 260194062Svanhu 261194062Svanhu if (New) { 262194062Svanhu // The SRW implicit def is dead. 263105197Ssam New->getOperand(3).setIsDead(); 264105197Ssam 265105197Ssam // Replace the pseudo instruction with a new instruction... 266105197Ssam MBB.insert(I, New); 267105197Ssam } 268105197Ssam } 269105197Ssam } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 270105197Ssam // If we are performing frame pointer elimination and if the callee pops 271105197Ssam // something off the stack pointer, add it back. 272105197Ssam if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 273105197Ssam MachineInstr *Old = I; 274105197Ssam MachineInstr *New = 275105197Ssam BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri), 276105197Ssam MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt); 277105197Ssam // The SRW implicit def is dead. 278105197Ssam New->getOperand(3).setIsDead(); 279105197Ssam 280105197Ssam MBB.insert(I, New); 281105197Ssam } 282105197Ssam } 283105197Ssam 284105197Ssam MBB.erase(I); 285105197Ssam} 286105197Ssam 287105197Ssamvoid 288105197SsamMSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 289252028Sae RegScavenger *) const { 290252028Sae // Create a frame entry for the FPW register that must be saved. 291252028Sae if (hasFP(MF)) { 292252028Sae int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true); 293252028Sae (void)FrameIdx; 294252028Sae assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 295252028Sae "Slot for FPW register must be last in order to be found!"); 296252028Sae } 297105197Ssam} 298105197Ssam