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/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/MachineModuleInfo.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/IR/DataLayout.h" 23 #include "llvm/IR/Function.h" 24 #include "llvm/Support/CommandLine.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) 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 = std::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 106 void 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 = std::prev(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? 179 bool 180 MSP430FrameLowering::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 205 bool 206 MSP430FrameLowering::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 225 void MSP430FrameLowering:: 226 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, 227 MachineBasicBlock::iterator I) const { 228 const MSP430InstrInfo &TII = 229 *static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo()); 230 unsigned StackAlign = getStackAlignment(); 231 232 if (!hasReservedCallFrame(MF)) { 233 // If the stack pointer can be changed after prologue, turn the 234 // adjcallstackup instruction into a 'sub SPW, <amt>' and the 235 // adjcallstackdown instruction into 'add SPW, <amt>' 236 // TODO: consider using push / pop instead of sub + store / add 237 MachineInstr *Old = I; 238 uint64_t Amount = Old->getOperand(0).getImm(); 239 if (Amount != 0) { 240 // We need to keep the stack aligned properly. To do this, we round the 241 // amount of space needed for the outgoing arguments up to the next 242 // alignment boundary. 243 Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; 244 245 MachineInstr *New = nullptr; 246 if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) { 247 New = BuildMI(MF, Old->getDebugLoc(), 248 TII.get(MSP430::SUB16ri), MSP430::SPW) 249 .addReg(MSP430::SPW).addImm(Amount); 250 } else { 251 assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode()); 252 // factor out the amount the callee already popped. 253 uint64_t CalleeAmt = Old->getOperand(1).getImm(); 254 Amount -= CalleeAmt; 255 if (Amount) 256 New = BuildMI(MF, Old->getDebugLoc(), 257 TII.get(MSP430::ADD16ri), MSP430::SPW) 258 .addReg(MSP430::SPW).addImm(Amount); 259 } 260 261 if (New) { 262 // The SRW implicit def is dead. 263 New->getOperand(3).setIsDead(); 264 265 // Replace the pseudo instruction with a new instruction... 266 MBB.insert(I, New); 267 } 268 } 269 } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 270 // If we are performing frame pointer elimination and if the callee pops 271 // something off the stack pointer, add it back. 272 if (uint64_t CalleeAmt = I->getOperand(1).getImm()) { 273 MachineInstr *Old = I; 274 MachineInstr *New = 275 BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri), 276 MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt); 277 // The SRW implicit def is dead. 278 New->getOperand(3).setIsDead(); 279 280 MBB.insert(I, New); 281 } 282 } 283 284 MBB.erase(I); 285 } 286 287 void 288 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 289 RegScavenger *) const { 290 // Create a frame entry for the FPW register that must be saved. 291 if (hasFP(MF)) { 292 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true); 293 (void)FrameIdx; 294 assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && 295 "Slot for FPW register must be last in order to be found!"); 296 } 297 } 298