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 "MSP430Subtarget.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/IR/DataLayout.h" 24 #include "llvm/IR/Function.h" 25 #include "llvm/Target/TargetOptions.h" 26 27 using namespace llvm; 28 29 bool 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 37 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 38 return !MF.getFrameInfo()->hasVarSizedObjects(); 39 } 40 41 void MSP430FrameLowering::emitPrologue(MachineFunction &MF, 42 MachineBasicBlock &MBB) const { 43 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 44 MachineFrameInfo *MFI = MF.getFrameInfo(); 45 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 46 const MSP430InstrInfo &TII = 47 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo()); 48 49 MachineBasicBlock::iterator MBBI = MBB.begin(); 50 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 51 52 // Get the number of bytes to allocate from the FrameInfo. 53 uint64_t StackSize = MFI->getStackSize(); 54 55 uint64_t NumBytes = 0; 56 if (hasFP(MF)) { 57 // Calculate required stack adjustment 58 uint64_t FrameSize = StackSize - 2; 59 NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); 60 61 // Get the offset of the stack slot for the EBP register... which is 62 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 63 // Update the frame offset adjustment. 64 MFI->setOffsetAdjustment(-NumBytes); 65 66 // Save FP into the appropriate stack slot... 67 BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) 68 .addReg(MSP430::FP, RegState::Kill); 69 70 // Update FP with the new base value... 71 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FP) 72 .addReg(MSP430::SP); 73 74 // Mark the FramePtr as live-in in every block except the entry. 75 for (MachineFunction::iterator I = std::next(MF.begin()), E = MF.end(); 76 I != E; ++I) 77 I->addLiveIn(MSP430::FP); 78 79 } else 80 NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); 81 82 // Skip the callee-saved push instructions. 83 while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r)) 84 ++MBBI; 85 86 if (MBBI != MBB.end()) 87 DL = MBBI->getDebugLoc(); 88 89 if (NumBytes) { // adjust stack pointer: SP -= numbytes 90 // If there is an SUB16ri of SP immediately before this instruction, merge 91 // the two. 92 //NumBytes -= mergeSPUpdates(MBB, MBBI, true); 93 // If there is an ADD16ri or SUB16ri of SP immediately after this 94 // instruction, merge the two instructions. 95 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); 96 97 if (NumBytes) { 98 MachineInstr *MI = 99 BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP) 100 .addReg(MSP430::SP).addImm(NumBytes); 101 // The SRW implicit def is dead. 102 MI->getOperand(3).setIsDead(); 103 } 104 } 105 } 106 107 void MSP430FrameLowering::emitEpilogue(MachineFunction &MF, 108 MachineBasicBlock &MBB) const { 109 const MachineFrameInfo *MFI = MF.getFrameInfo(); 110 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 111 const MSP430InstrInfo &TII = 112 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo()); 113 114 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 115 unsigned RetOpcode = MBBI->getOpcode(); 116 DebugLoc DL = MBBI->getDebugLoc(); 117 118 switch (RetOpcode) { 119 case MSP430::RET: 120 case MSP430::RETI: break; // These are ok 121 default: 122 llvm_unreachable("Can only insert epilog into returning blocks"); 123 } 124 125 // Get the number of bytes to allocate from the FrameInfo 126 uint64_t StackSize = MFI->getStackSize(); 127 unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); 128 uint64_t NumBytes = 0; 129 130 if (hasFP(MF)) { 131 // Calculate required stack adjustment 132 uint64_t FrameSize = StackSize - 2; 133 NumBytes = FrameSize - CSSize; 134 135 // pop FP. 136 BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FP); 137 } else 138 NumBytes = StackSize - CSSize; 139 140 // Skip the callee-saved pop instructions. 141 while (MBBI != MBB.begin()) { 142 MachineBasicBlock::iterator PI = std::prev(MBBI); 143 unsigned Opc = PI->getOpcode(); 144 if (Opc != MSP430::POP16r && !PI->isTerminator()) 145 break; 146 --MBBI; 147 } 148 149 DL = MBBI->getDebugLoc(); 150 151 // If there is an ADD16ri or SUB16ri of SP immediately before this 152 // instruction, merge the two instructions. 153 //if (NumBytes || MFI->hasVarSizedObjects()) 154 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 155 156 if (MFI->hasVarSizedObjects()) { 157 BuildMI(MBB, MBBI, DL, 158 TII.get(MSP430::MOV16rr), MSP430::SP).addReg(MSP430::FP); 159 if (CSSize) { 160 MachineInstr *MI = 161 BuildMI(MBB, MBBI, DL, 162 TII.get(MSP430::SUB16ri), MSP430::SP) 163 .addReg(MSP430::SP).addImm(CSSize); 164 // The SRW implicit def is dead. 165 MI->getOperand(3).setIsDead(); 166 } 167 } else { 168 // adjust stack pointer back: SP += numbytes 169 if (NumBytes) { 170 MachineInstr *MI = 171 BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP) 172 .addReg(MSP430::SP).addImm(NumBytes); 173 // The SRW implicit def is dead. 174 MI->getOperand(3).setIsDead(); 175 } 176 } 177 } 178 179 // FIXME: Can we eleminate these in favour of generic code? 180 bool 181 MSP430FrameLowering::spillCalleeSavedRegisters(MachineBasicBlock &MBB, 182 MachineBasicBlock::iterator MI, 183 const std::vector<CalleeSavedInfo> &CSI, 184 const TargetRegisterInfo *TRI) const { 185 if (CSI.empty()) 186 return false; 187 188 DebugLoc DL; 189 if (MI != MBB.end()) DL = MI->getDebugLoc(); 190 191 MachineFunction &MF = *MBB.getParent(); 192 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 193 MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>(); 194 MFI->setCalleeSavedFrameSize(CSI.size() * 2); 195 196 for (unsigned i = CSI.size(); i != 0; --i) { 197 unsigned Reg = CSI[i-1].getReg(); 198 // Add the callee-saved register as live-in. It's killed at the spill. 199 MBB.addLiveIn(Reg); 200 BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r)) 201 .addReg(Reg, RegState::Kill); 202 } 203 return true; 204 } 205 206 bool 207 MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 208 MachineBasicBlock::iterator MI, 209 const std::vector<CalleeSavedInfo> &CSI, 210 const TargetRegisterInfo *TRI) const { 211 if (CSI.empty()) 212 return false; 213 214 DebugLoc DL; 215 if (MI != MBB.end()) DL = MI->getDebugLoc(); 216 217 MachineFunction &MF = *MBB.getParent(); 218 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 219 220 for (unsigned i = 0, e = CSI.size(); i != e; ++i) 221 BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), CSI[i].getReg()); 222 223 return true; 224 } 225 226 MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr( 227 MachineFunction &MF, MachineBasicBlock &MBB, 228 MachineBasicBlock::iterator I) const { 229 const MSP430InstrInfo &TII = 230 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo()); 231 unsigned StackAlign = getStackAlignment(); 232 233 if (!hasReservedCallFrame(MF)) { 234 // If the stack pointer can be changed after prologue, turn the 235 // adjcallstackup instruction into a 'sub SP, <amt>' and the 236 // adjcallstackdown instruction into 'add SP, <amt>' 237 // TODO: consider using push / pop instead of sub + store / add 238 MachineInstr &Old = *I; 239 uint64_t Amount = Old.getOperand(0).getImm(); 240 if (Amount != 0) { 241 // We need to keep the stack aligned properly. To do this, we round the 242 // amount of space needed for the outgoing arguments up to the next 243 // alignment boundary. 244 Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 245 246 MachineInstr *New = nullptr; 247 if (Old.getOpcode() == TII.getCallFrameSetupOpcode()) { 248 New = 249 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP) 250 .addReg(MSP430::SP) 251 .addImm(Amount); 252 } else { 253 assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode()); 254 // factor out the amount the callee already popped. 255 uint64_t CalleeAmt = Old.getOperand(1).getImm(); 256 Amount -= CalleeAmt; 257 if (Amount) 258 New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri), 259 MSP430::SP) 260 .addReg(MSP430::SP) 261 .addImm(Amount); 262 } 263 264 if (New) { 265 // The SRW implicit def is dead. 266 New->getOperand(3).setIsDead(); 267 268 // Replace the pseudo instruction with a new instruction... 269 MBB.insert(I, New); 270 } 271 } 272 } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 273 // If we are performing frame pointer elimination and if the callee pops 274 // something off the stack pointer, add it back. 275 if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 276 MachineInstr &Old = *I; 277 MachineInstr *New = 278 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP) 279 .addReg(MSP430::SP) 280 .addImm(CalleeAmt); 281 // The SRW implicit def is dead. 282 New->getOperand(3).setIsDead(); 283 284 MBB.insert(I, New); 285 } 286 } 287 288 return MBB.erase(I); 289 } 290 291 void 292 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 293 RegScavenger *) const { 294 // Create a frame entry for the FP register that must be saved. 295 if (hasFP(MF)) { 296 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true); 297 (void)FrameIdx; 298 assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 299 "Slot for FP register must be last in order to be found!"); 300 } 301 } 302