1//===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the MSP430 implementation of TargetFrameLowering class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "MSP430FrameLowering.h" 15#include "MSP430InstrInfo.h" 16#include "MSP430MachineFunctionInfo.h" 17#include "llvm/Function.h" 18#include "llvm/CodeGen/MachineFrameInfo.h" 19#include "llvm/CodeGen/MachineFunction.h" 20#include "llvm/CodeGen/MachineInstrBuilder.h" 21#include "llvm/CodeGen/MachineModuleInfo.h" 22#include "llvm/CodeGen/MachineRegisterInfo.h" 23#include "llvm/Target/TargetData.h" 24#include "llvm/Target/TargetOptions.h" 25#include "llvm/Support/CommandLine.h" 26 27using namespace llvm; 28 29bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const { 30 const MachineFrameInfo *MFI = MF.getFrameInfo(); 31 32 return (MF.getTarget().Options.DisableFramePointerElim(MF) || 33 MF.getFrameInfo()->hasVarSizedObjects() || 34 MFI->isFrameAddressTaken()); 35} 36 37bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 38 return !MF.getFrameInfo()->hasVarSizedObjects(); 39} 40 41void MSP430FrameLowering::emitPrologue(MachineFunction &MF) const { 42 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB 43 MachineFrameInfo *MFI = MF.getFrameInfo(); 44 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 45 const MSP430InstrInfo &TII = 46 *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 47 48 MachineBasicBlock::iterator MBBI = MBB.begin(); 49 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 50 51 // Get the number of bytes to allocate from the FrameInfo. 52 uint64_t StackSize = MFI->getStackSize(); 53 54 uint64_t NumBytes = 0; 55 if (hasFP(MF)) { 56 // Calculate required stack adjustment 57 uint64_t FrameSize = StackSize - 2; 58 NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); 59 60 // Get the offset of the stack slot for the EBP register... which is 61 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 62 // Update the frame offset adjustment. 63 MFI->setOffsetAdjustment(-NumBytes); 64 65 // Save FPW into the appropriate stack slot... 66 BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) 67 .addReg(MSP430::FPW, RegState::Kill); 68 69 // Update FPW with the new base value... 70 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW) 71 .addReg(MSP430::SPW); 72 73 // Mark the FramePtr as live-in in every block except the entry. 74 for (MachineFunction::iterator I = llvm::next(MF.begin()), E = MF.end(); 75 I != E; ++I) 76 I->addLiveIn(MSP430::FPW); 77 78 } else 79 NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); 80 81 // Skip the callee-saved push instructions. 82 while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r)) 83 ++MBBI; 84 85 if (MBBI != MBB.end()) 86 DL = MBBI->getDebugLoc(); 87 88 if (NumBytes) { // adjust stack pointer: SPW -= numbytes 89 // If there is an SUB16ri of SPW immediately before this instruction, merge 90 // the two. 91 //NumBytes -= mergeSPUpdates(MBB, MBBI, true); 92 // If there is an ADD16ri or SUB16ri of SPW immediately after this 93 // instruction, merge the two instructions. 94 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); 95 96 if (NumBytes) { 97 MachineInstr *MI = 98 BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW) 99 .addReg(MSP430::SPW).addImm(NumBytes); 100 // The SRW implicit def is dead. 101 MI->getOperand(3).setIsDead(); 102 } 103 } 104} 105 106void MSP430FrameLowering::emitEpilogue(MachineFunction &MF, 107 MachineBasicBlock &MBB) const { 108 const MachineFrameInfo *MFI = MF.getFrameInfo(); 109 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 110 const MSP430InstrInfo &TII = 111 *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 112 113 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 114 unsigned RetOpcode = MBBI->getOpcode(); 115 DebugLoc DL = MBBI->getDebugLoc(); 116 117 switch (RetOpcode) { 118 case MSP430::RET: 119 case MSP430::RETI: break; // These are ok 120 default: 121 llvm_unreachable("Can only insert epilog into returning blocks"); 122 } 123 124 // Get the number of bytes to allocate from the FrameInfo 125 uint64_t StackSize = MFI->getStackSize(); 126 unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); 127 uint64_t NumBytes = 0; 128 129 if (hasFP(MF)) { 130 // Calculate required stack adjustment 131 uint64_t FrameSize = StackSize - 2; 132 NumBytes = FrameSize - CSSize; 133 134 // pop FPW. 135 BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW); 136 } else 137 NumBytes = StackSize - CSSize; 138 139 // Skip the callee-saved pop instructions. 140 while (MBBI != MBB.begin()) { 141 MachineBasicBlock::iterator PI = prior(MBBI); 142 unsigned Opc = PI->getOpcode(); 143 if (Opc != MSP430::POP16r && !PI->isTerminator()) 144 break; 145 --MBBI; 146 } 147 148 DL = MBBI->getDebugLoc(); 149 150 // If there is an ADD16ri or SUB16ri of SPW immediately before this 151 // instruction, merge the two instructions. 152 //if (NumBytes || MFI->hasVarSizedObjects()) 153 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 154 155 if (MFI->hasVarSizedObjects()) { 156 BuildMI(MBB, MBBI, DL, 157 TII.get(MSP430::MOV16rr), MSP430::SPW).addReg(MSP430::FPW); 158 if (CSSize) { 159 MachineInstr *MI = 160 BuildMI(MBB, MBBI, DL, 161 TII.get(MSP430::SUB16ri), MSP430::SPW) 162 .addReg(MSP430::SPW).addImm(CSSize); 163 // The SRW implicit def is dead. 164 MI->getOperand(3).setIsDead(); 165 } 166 } else { 167 // adjust stack pointer back: SPW += numbytes 168 if (NumBytes) { 169 MachineInstr *MI = 170 BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW) 171 .addReg(MSP430::SPW).addImm(NumBytes); 172 // The SRW implicit def is dead. 173 MI->getOperand(3).setIsDead(); 174 } 175 } 176} 177 178// FIXME: Can we eleminate these in favour of generic code? 179bool 180MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 181 MachineBasicBlock::iterator MI, 182 const std::vector<CalleeSavedInfo> &CSI, 183 const TargetRegisterInfo *TRI) const { 184 if (CSI.empty()) 185 return false; 186 187 DebugLoc DL; 188 if (MI != MBB.end()) DL = MI->getDebugLoc(); 189 190 MachineFunction &MF = *MBB.getParent(); 191 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 192 MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>(); 193 MFI->setCalleeSavedFrameSize(CSI.size() * 2); 194 195 for (unsigned i = CSI.size(); i != 0; --i) { 196 unsigned Reg = CSI[i-1].getReg(); 197 // Add the callee-saved register as live-in. It's killed at the spill. 198 MBB.addLiveIn(Reg); 199 BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r)) 200 .addReg(Reg, RegState::Kill); 201 } 202 return true; 203} 204 205bool 206MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 207 MachineBasicBlock::iterator MI, 208 const std::vector<CalleeSavedInfo> &CSI, 209 const TargetRegisterInfo *TRI) const { 210 if (CSI.empty()) 211 return false; 212 213 DebugLoc DL; 214 if (MI != MBB.end()) DL = MI->getDebugLoc(); 215 216 MachineFunction &MF = *MBB.getParent(); 217 const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 218 219 for (unsigned i = 0, e = CSI.size(); i != e; ++i) 220 BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg()); 221 222 return true; 223} 224