1234353Sdim//===-- MSP430FrameLowering.cpp - MSP430 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 MSP430 implementation of TargetFrameLowering class. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14218885Sdim#include "MSP430FrameLowering.h" 15218885Sdim#include "MSP430InstrInfo.h" 16218885Sdim#include "MSP430MachineFunctionInfo.h" 17218885Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 18218885Sdim#include "llvm/CodeGen/MachineFunction.h" 19218885Sdim#include "llvm/CodeGen/MachineInstrBuilder.h" 20218885Sdim#include "llvm/CodeGen/MachineModuleInfo.h" 21218885Sdim#include "llvm/CodeGen/MachineRegisterInfo.h" 22249423Sdim#include "llvm/IR/DataLayout.h" 23249423Sdim#include "llvm/IR/Function.h" 24249423Sdim#include "llvm/Support/CommandLine.h" 25218885Sdim#include "llvm/Target/TargetOptions.h" 26218885Sdim 27218885Sdimusing namespace llvm; 28218885Sdim 29218885Sdimbool MSP430FrameLowering::hasFP(const MachineFunction &MF) const { 30218885Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 31218885Sdim 32234353Sdim return (MF.getTarget().Options.DisableFramePointerElim(MF) || 33218885Sdim MF.getFrameInfo()->hasVarSizedObjects() || 34218885Sdim MFI->isFrameAddressTaken()); 35218885Sdim} 36218885Sdim 37218885Sdimbool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 38218885Sdim return !MF.getFrameInfo()->hasVarSizedObjects(); 39218885Sdim} 40218885Sdim 41218885Sdimvoid MSP430FrameLowering::emitPrologue(MachineFunction &MF) const { 42218885Sdim MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 43218885Sdim MachineFrameInfo *MFI = MF.getFrameInfo(); 44218885Sdim MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 45218885Sdim const MSP430InstrInfo &TII = 46218885Sdim *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 47218885Sdim 48218885Sdim MachineBasicBlock::iterator MBBI = MBB.begin(); 49218885Sdim DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 50218885Sdim 51218885Sdim // Get the number of bytes to allocate from the FrameInfo. 52218885Sdim uint64_t StackSize = MFI->getStackSize(); 53218885Sdim 54218885Sdim uint64_t NumBytes = 0; 55218885Sdim if (hasFP(MF)) { 56218885Sdim // Calculate required stack adjustment 57218885Sdim uint64_t FrameSize = StackSize - 2; 58218885Sdim NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); 59218885Sdim 60218885Sdim // Get the offset of the stack slot for the EBP register... which is 61218885Sdim // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 62218885Sdim // Update the frame offset adjustment. 63218885Sdim MFI->setOffsetAdjustment(-NumBytes); 64218885Sdim 65218885Sdim // Save FPW into the appropriate stack slot... 66218885Sdim BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) 67218885Sdim .addReg(MSP430::FPW, RegState::Kill); 68218885Sdim 69218885Sdim // Update FPW with the new base value... 70218885Sdim BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW) 71218885Sdim .addReg(MSP430::SPW); 72218885Sdim 73218885Sdim // Mark the FramePtr as live-in in every block except the entry. 74218885Sdim for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); 75218885Sdim I != E; ++I) 76218885Sdim I->addLiveIn(MSP430::FPW); 77218885Sdim 78218885Sdim } else 79218885Sdim NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); 80218885Sdim 81218885Sdim // Skip the callee-saved push instructions. 82218885Sdim while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r)) 83218885Sdim ++MBBI; 84218885Sdim 85218885Sdim if (MBBI != MBB.end()) 86218885Sdim DL = MBBI->getDebugLoc(); 87218885Sdim 88218885Sdim if (NumBytes) { // adjust stack pointer: SPW -= numbytes 89218885Sdim // If there is an SUB16ri of SPW immediately before this instruction, merge 90218885Sdim // the two. 91218885Sdim //NumBytes -= mergeSPUpdates(MBB, MBBI, true); 92218885Sdim // If there is an ADD16ri or SUB16ri of SPW immediately after this 93218885Sdim // instruction, merge the two instructions. 94218885Sdim // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); 95218885Sdim 96218885Sdim if (NumBytes) { 97218885Sdim MachineInstr *MI = 98218885Sdim BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW) 99218885Sdim .addReg(MSP430::SPW).addImm(NumBytes); 100218885Sdim // The SRW implicit def is dead. 101218885Sdim MI->getOperand(3).setIsDead(); 102218885Sdim } 103218885Sdim } 104218885Sdim} 105218885Sdim 106218885Sdimvoid MSP430FrameLowering::emitEpilogue(MachineFunction &MF, 107218885Sdim MachineBasicBlock &MBB) const { 108218885Sdim const MachineFrameInfo *MFI = MF.getFrameInfo(); 109218885Sdim MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 110218885Sdim const MSP430InstrInfo &TII = 111218885Sdim *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 112218885Sdim 113218885Sdim MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 114218885Sdim unsigned RetOpcode = MBBI->getOpcode(); 115218885Sdim DebugLoc DL = MBBI->getDebugLoc(); 116218885Sdim 117218885Sdim switch (RetOpcode) { 118218885Sdim case MSP430::RET: 119218885Sdim case MSP430::RETI: break; // These are ok 120218885Sdim default: 121218885Sdim llvm_unreachable("Can only insert epilog into returning blocks"); 122218885Sdim } 123218885Sdim 124218885Sdim // Get the number of bytes to allocate from the FrameInfo 125218885Sdim uint64_t StackSize = MFI->getStackSize(); 126218885Sdim unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); 127218885Sdim uint64_t NumBytes = 0; 128218885Sdim 129218885Sdim if (hasFP(MF)) { 130218885Sdim // Calculate required stack adjustment 131218885Sdim uint64_t FrameSize = StackSize - 2; 132218885Sdim NumBytes = FrameSize - CSSize; 133218885Sdim 134218885Sdim // pop FPW. 135218885Sdim BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW); 136218885Sdim } else 137218885Sdim NumBytes = StackSize - CSSize; 138218885Sdim 139218885Sdim // Skip the callee-saved pop instructions. 140218885Sdim while (MBBI != MBB.begin()) { 141218885Sdim MachineBasicBlock::iterator PI = prior(MBBI); 142218885Sdim unsigned Opc = PI->getOpcode(); 143234353Sdim if (Opc != MSP430::POP16r && !PI->isTerminator()) 144218885Sdim break; 145218885Sdim --MBBI; 146218885Sdim } 147218885Sdim 148218885Sdim DL = MBBI->getDebugLoc(); 149218885Sdim 150218885Sdim // If there is an ADD16ri or SUB16ri of SPW immediately before this 151218885Sdim // instruction, merge the two instructions. 152218885Sdim //if (NumBytes || MFI->hasVarSizedObjects()) 153218885Sdim // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 154218885Sdim 155218885Sdim if (MFI->hasVarSizedObjects()) { 156218885Sdim BuildMI(MBB, MBBI, DL, 157218885Sdim TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW); 158218885Sdim if (CSSize) { 159218885Sdim MachineInstr *MI = 160218885Sdim BuildMI(MBB, MBBI, DL, 161218885Sdim TII.get(MSP430::SUB16ri), MSP430::SPW) 162218885Sdim .addReg(MSP430::SPW).addImm(CSSize); 163218885Sdim // The SRW implicit def is dead. 164218885Sdim MI->getOperand(3).setIsDead(); 165218885Sdim } 166218885Sdim } else { 167218885Sdim // adjust stack pointer back: SPW += numbytes 168218885Sdim if (NumBytes) { 169218885Sdim MachineInstr *MI = 170218885Sdim BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW) 171218885Sdim .addReg(MSP430::SPW).addImm(NumBytes); 172218885Sdim // The SRW implicit def is dead. 173218885Sdim MI->getOperand(3).setIsDead(); 174218885Sdim } 175218885Sdim } 176218885Sdim} 177218885Sdim 178218885Sdim// FIXME: Can we eleminate these in favour of generic code? 179218885Sdimbool 180218885SdimMSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 181218885Sdim MachineBasicBlock::iterator MI, 182218885Sdim const std::vector<CalleeSavedInfo> &CSI, 183218885Sdim const TargetRegisterInfo *TRI) const { 184218885Sdim if (CSI.empty()) 185218885Sdim return false; 186218885Sdim 187218885Sdim DebugLoc DL; 188218885Sdim if (MI != MBB.end()) DL = MI->getDebugLoc(); 189218885Sdim 190218885Sdim MachineFunction &MF = *MBB.getParent(); 191218885Sdim const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 192218885Sdim MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>(); 193218885Sdim MFI->setCalleeSavedFrameSize(CSI.size() * 2); 194218885Sdim 195218885Sdim for (unsigned i = CSI.size(); i != 0; --i) { 196218885Sdim unsigned Reg = CSI[i-1].getReg(); 197218885Sdim // Add the callee-saved register as live-in. It's killed at the spill. 198218885Sdim MBB.addLiveIn(Reg); 199218885Sdim BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r)) 200218885Sdim .addReg(Reg, RegState::Kill); 201218885Sdim } 202218885Sdim return true; 203218885Sdim} 204218885Sdim 205218885Sdimbool 206218885SdimMSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 207218885Sdim MachineBasicBlock::iterator MI, 208218885Sdim const std::vector<CalleeSavedInfo> &CSI, 209218885Sdim const TargetRegisterInfo *TRI) const { 210218885Sdim if (CSI.empty()) 211218885Sdim return false; 212218885Sdim 213218885Sdim DebugLoc DL; 214218885Sdim if (MI != MBB.end()) DL = MI->getDebugLoc(); 215218885Sdim 216218885Sdim MachineFunction &MF = *MBB.getParent(); 217218885Sdim const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 218218885Sdim 219218885Sdim for (unsigned i = 0, e = CSI.size(); i != e; ++i) 220218885Sdim BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg()); 221218885Sdim 222218885Sdim return true; 223218885Sdim} 224243830Sdim 225249423Sdimvoid MSP430FrameLowering:: 226249423SdimeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 227249423Sdim MachineBasicBlock::iterator I) const { 228249423Sdim const MSP430InstrInfo &TII = 229249423Sdim *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 230249423Sdim unsigned StackAlign = getStackAlignment(); 231249423Sdim 232249423Sdim if (!hasReservedCallFrame(MF)) { 233249423Sdim // If the stack pointer can be changed after prologue, turn the 234249423Sdim // adjcallstackup instruction into a 'sub SPW, <amt>' and the 235249423Sdim // adjcallstackdown instruction into 'add SPW, <amt>' 236249423Sdim // TODO: consider using push / pop instead of sub + store / add 237249423Sdim MachineInstr *Old = I; 238249423Sdim uint64_t Amount = Old->getOperand(0).getImm(); 239249423Sdim if (Amount != 0) { 240249423Sdim // We need to keep the stack aligned properly. To do this, we round the 241249423Sdim // amount of space needed for the outgoing arguments up to the next 242249423Sdim // alignment boundary. 243249423Sdim Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 244249423Sdim 245249423Sdim MachineInstr *New = 0; 246249423Sdim if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) { 247249423Sdim New = BuildMI(MF, Old->getDebugLoc(), 248249423Sdim TII.get(MSP430::SUB16ri), MSP430::SPW) 249249423Sdim .addReg(MSP430::SPW).addImm(Amount); 250249423Sdim } else { 251249423Sdim assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode()); 252249423Sdim // factor out the amount the callee already popped. 253249423Sdim uint64_t CalleeAmt = Old->getOperand(1).getImm(); 254249423Sdim Amount -= CalleeAmt; 255249423Sdim if (Amount) 256249423Sdim New = BuildMI(MF, Old->getDebugLoc(), 257249423Sdim TII.get(MSP430::ADD16ri), MSP430::SPW) 258249423Sdim .addReg(MSP430::SPW).addImm(Amount); 259249423Sdim } 260249423Sdim 261249423Sdim if (New) { 262249423Sdim // The SRW implicit def is dead. 263249423Sdim New->getOperand(3).setIsDead(); 264249423Sdim 265249423Sdim // Replace the pseudo instruction with a new instruction... 266249423Sdim MBB.insert(I, New); 267249423Sdim } 268249423Sdim } 269249423Sdim } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 270249423Sdim // If we are performing frame pointer elimination and if the callee pops 271249423Sdim // something off the stack pointer, add it back. 272249423Sdim if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 273249423Sdim MachineInstr *Old = I; 274249423Sdim MachineInstr *New = 275249423Sdim BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri), 276249423Sdim MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt); 277249423Sdim // The SRW implicit def is dead. 278249423Sdim New->getOperand(3).setIsDead(); 279249423Sdim 280249423Sdim MBB.insert(I, New); 281249423Sdim } 282249423Sdim } 283249423Sdim 284249423Sdim MBB.erase(I); 285249423Sdim} 286249423Sdim 287243830Sdimvoid 288249423SdimMSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 289249423Sdim RegScavenger *) const { 290243830Sdim // Create a frame entry for the FPW register that must be saved. 291249423Sdim if (hasFP(MF)) { 292243830Sdim int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true); 293243830Sdim (void)FrameIdx; 294243830Sdim assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 295243830Sdim "Slot for FPW register must be last in order to be found!"); 296243830Sdim } 297243830Sdim} 298