131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===// 233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// The LLVM Compiler Infrastructure 433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// This file is distributed under the University of Illinois Open Source 633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// License. See LICENSE.TXT for details. 733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov// This file contains the MSP430 implementation of TargetFrameLowering class. 1133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov// 1233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov//===----------------------------------------------------------------------===// 1333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1416c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "MSP430FrameLowering.h" 1533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MSP430InstrInfo.h" 1633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "MSP430MachineFunctionInfo.h" 1733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFrameInfo.h" 1833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineFunction.h" 1933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineInstrBuilder.h" 2033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineModuleInfo.h" 2133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/CodeGen/MachineRegisterInfo.h" 220b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 230b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 2433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov#include "llvm/Support/CommandLine.h" 25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetOptions.h" 2633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikovusing namespace llvm; 2833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 2916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MSP430FrameLowering::hasFP(const MachineFunction &MF) const { 30d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 31d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 328a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky return (MF.getTarget().Options.DisableFramePointerElim(MF) || 33d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MF.getFrameInfo()->hasVarSizedObjects() || 34d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov MFI->isFrameAddressTaken()); 35d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 36d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 3716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovbool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 38d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov return !MF.getFrameInfo()->hasVarSizedObjects(); 39d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov} 40d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov 4116c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MSP430FrameLowering::emitPrologue(MachineFunction &MF) const { 4233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 4333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineFrameInfo *MFI = MF.getFrameInfo(); 4433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 4533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MSP430InstrInfo &TII = 4633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 4733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 4833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineBasicBlock::iterator MBBI = MBB.begin(); 4933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 5033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 5133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo. 5233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 5333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 5433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 55d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 5633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment 5733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - 2; 5833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); 5933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 6033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the offset of the stack slot for the EBP register... which is 6133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 6233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update the frame offset adjustment. 6333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MFI->setOffsetAdjustment(-NumBytes); 6433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 6533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Save FPW into the appropriate stack slot... 6633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) 6733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MSP430::FPW, RegState::Kill); 6833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 6933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Update FPW with the new base value... 7033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW) 7133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MSP430::SPW); 7233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 7333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Mark the FramePtr as live-in in every block except the entry. 7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end(); 7533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I != E; ++I) 7633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov I->addLiveIn(MSP430::FPW); 7733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 7833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else 7933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); 8033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved push instructions. 8233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r)) 8333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov ++MBBI; 8433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MBBI != MBB.end()) 8633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBBI->getDebugLoc(); 8733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 8833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) { // adjust stack pointer: SPW -= numbytes 8933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an SUB16ri of SPW immediately before this instruction, merge 9033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // the two. 9133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov //NumBytes -= mergeSPUpdates(MBB, MBBI, true); 9233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD16ri or SUB16ri of SPW immediately after this 9333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 9433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); 9533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 9633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) { 9733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 9833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW) 9933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MSP430::SPW).addImm(NumBytes); 10033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The SRW implicit def is dead. 10133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); 10233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 10333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 10433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 10533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 10616c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikovvoid MSP430FrameLowering::emitEpilogue(MachineFunction &MF, 10716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov MachineBasicBlock &MBB) const { 10833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MachineFrameInfo *MFI = MF.getFrameInfo(); 10933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 11033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov const MSP430InstrInfo &TII = 11133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 11233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 1134f28c1c71450c711e96aa283de53739d8b4504cdJakob Stoklund Olesen MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 11433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned RetOpcode = MBBI->getOpcode(); 11533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DebugLoc DL = MBBI->getDebugLoc(); 11633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 11733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov switch (RetOpcode) { 11833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case MSP430::RET: 11933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov case MSP430::RETI: break; // These are ok 12033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov default: 12133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov llvm_unreachable("Can only insert epilog into returning blocks"); 12233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 12333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 12433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Get the number of bytes to allocate from the FrameInfo 12533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t StackSize = MFI->getStackSize(); 12633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); 12733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t NumBytes = 0; 12833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 129d0c38176690e9602a93a20a43f1bd084564a8116Anton Korobeynikov if (hasFP(MF)) { 13033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Calculate required stack adjustment 13133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov uint64_t FrameSize = StackSize - 2; 13233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = FrameSize - CSSize; 13333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 13433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // pop FPW. 13533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW); 13633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else 13733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov NumBytes = StackSize - CSSize; 13833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 13933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // Skip the callee-saved pop instructions. 14033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov while (MBBI != MBB.begin()) { 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineBasicBlock::iterator PI = std::prev(MBBI); 14233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov unsigned Opc = PI->getOpcode(); 1435a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng if (Opc != MSP430::POP16r && !PI->isTerminator()) 14433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov break; 14533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov --MBBI; 14633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 14733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 14833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov DL = MBBI->getDebugLoc(); 14933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 15033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // If there is an ADD16ri or SUB16ri of SPW immediately before this 15133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // instruction, merge the two instructions. 15233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov //if (NumBytes || MFI->hasVarSizedObjects()) 15333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 15433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov 15533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (MFI->hasVarSizedObjects()) { 15633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 15733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW); 15833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (CSSize) { 15933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 16033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, 16133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov TII.get(MSP430::SUB16ri), MSP430::SPW) 16233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MSP430::SPW).addImm(CSSize); 16333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The SRW implicit def is dead. 16433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); 16533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 16633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } else { 16733464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // adjust stack pointer back: SPW += numbytes 16833464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov if (NumBytes) { 16933464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MachineInstr *MI = 17033464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW) 17133464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov .addReg(MSP430::SPW).addImm(NumBytes); 17233464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov // The SRW implicit def is dead. 17333464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov MI->getOperand(3).setIsDead(); 17433464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 17533464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov } 17633464912237efaa0ed7060829e66b59055bdd48bAnton Korobeynikov} 177cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 178cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov// FIXME: Can we eleminate these in favour of generic code? 179cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikovbool 18016c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovMSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 181cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineBasicBlock::iterator MI, 182cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 183cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 184cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 185cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 186cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 187cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL; 188cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (MI != MBB.end()) DL = MI->getDebugLoc(); 189cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 190cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 191cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 192cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>(); 193cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MFI->setCalleeSavedFrameSize(CSI.size() * 2); 194cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 195cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = CSI.size(); i != 0; --i) { 196cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov unsigned Reg = CSI[i-1].getReg(); 197cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov // Add the callee-saved register as live-in. It's killed at the spill. 198cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MBB.addLiveIn(Reg); 199cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r)) 200cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov .addReg(Reg, RegState::Kill); 201cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov } 202cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 203cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 204cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 205cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikovbool 20616c29b5f285f375be53dabaa73e3e91107485fe4Anton KorobeynikovMSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 20716c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov MachineBasicBlock::iterator MI, 208cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const std::vector<CalleeSavedInfo> &CSI, 209cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetRegisterInfo *TRI) const { 210cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (CSI.empty()) 211cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return false; 212cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 213cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov DebugLoc DL; 214cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov if (MI != MBB.end()) DL = MI->getDebugLoc(); 215cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 216cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov MachineFunction &MF = *MBB.getParent(); 217cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 218cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 219cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov for (unsigned i = 0, e = CSI.size(); i != e; ++i) 220cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg()); 221cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov 222cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov return true; 223cd775ceff0b25a0b026f643a7990c2924bd310a3Anton Korobeynikov} 224e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov 225700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Benderskyvoid MSP430FrameLowering:: 226700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli BenderskyeliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 227700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineBasicBlock::iterator I) const { 228700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky const MSP430InstrInfo &TII = 229700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 230700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky unsigned StackAlign = getStackAlignment(); 231700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 232700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (!hasReservedCallFrame(MF)) { 233700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If the stack pointer can be changed after prologue, turn the 234700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // adjcallstackup instruction into a 'sub SPW, <amt>' and the 235700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // adjcallstackdown instruction into 'add SPW, <amt>' 236700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // TODO: consider using push / pop instead of sub + store / add 237700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr *Old = I; 238700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t Amount = Old->getOperand(0).getImm(); 239700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Amount != 0) { 240700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // We need to keep the stack aligned properly. To do this, we round the 241700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // amount of space needed for the outgoing arguments up to the next 242700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // alignment boundary. 243700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 244700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines MachineInstr *New = nullptr; 246700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) { 247700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New = BuildMI(MF, Old->getDebugLoc(), 248700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky TII.get(MSP430::SUB16ri), MSP430::SPW) 249700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(MSP430::SPW).addImm(Amount); 250700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else { 251700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode()); 252700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // factor out the amount the callee already popped. 253700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky uint64_t CalleeAmt = Old->getOperand(1).getImm(); 254700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky Amount -= CalleeAmt; 255700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (Amount) 256700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New = BuildMI(MF, Old->getDebugLoc(), 257700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky TII.get(MSP430::ADD16ri), MSP430::SPW) 258700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky .addReg(MSP430::SPW).addImm(Amount); 259700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 260700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 261700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (New) { 262700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // The SRW implicit def is dead. 263700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New->getOperand(3).setIsDead(); 264700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 265700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // Replace the pseudo instruction with a new instruction... 266700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.insert(I, New); 267700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 268700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 269700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 270700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // If we are performing frame pointer elimination and if the callee pops 271700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // something off the stack pointer, add it back. 272700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 273700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr *Old = I; 274700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MachineInstr *New = 275700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri), 276700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt); 277700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky // The SRW implicit def is dead. 278700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky New->getOperand(3).setIsDead(); 279700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 280700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.insert(I, New); 281700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 282700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky } 283700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 284700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky MBB.erase(I); 285700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky} 286700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky 287e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikovvoid 2883080d23fde4981835d8a7faf46c152441fadb11fHal FinkelMSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 2893080d23fde4981835d8a7faf46c152441fadb11fHal Finkel RegScavenger *) const { 290e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov // Create a frame entry for the FPW register that must be saved. 291700ed80d3da5e98e05ceb90e9bfb66058581a6dbEli Bendersky if (hasFP(MF)) { 292e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true); 293e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov (void)FrameIdx; 294e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 295e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov "Slot for FPW register must be last in order to be found!"); 296e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov } 297e4b33a115bb91c663c55061fd232fa839cc8c4caAnton Korobeynikov} 298