1 //===-- MSP430FrameLowering.cpp - MSP430 Frame Information ----------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the MSP430 implementation of TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "MSP430FrameLowering.h" 14 #include "MSP430InstrInfo.h" 15 #include "MSP430MachineFunctionInfo.h" 16 #include "MSP430Subtarget.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/Target/TargetOptions.h" 25 26 using namespace llvm; 27 28 bool MSP430FrameLowering::hasFP(const MachineFunction &MF) const { 29 const MachineFrameInfo &MFI = MF.getFrameInfo(); 30 31 return (MF.getTarget().Options.DisableFramePointerElim(MF) || 32 MF.getFrameInfo().hasVarSizedObjects() || 33 MFI.isFrameAddressTaken()); 34 } 35 36 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 37 return !MF.getFrameInfo().hasVarSizedObjects(); 38 } 39 40 void MSP430FrameLowering::emitPrologue(MachineFunction &MF, 41 MachineBasicBlock &MBB) const { 42 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 43 MachineFrameInfo &MFI = MF.getFrameInfo(); 44 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 45 const MSP430InstrInfo &TII = 46 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().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 FP into the appropriate stack slot... 66 BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) 67 .addReg(MSP430::FP, RegState::Kill); 68 69 // Update FP with the new base value... 70 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FP) 71 .addReg(MSP430::SP); 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::FP); 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: SP -= numbytes 89 // If there is an SUB16ri of SP immediately before this instruction, merge 90 // the two. 91 //NumBytes -= mergeSPUpdates(MBB, MBBI, true); 92 // If there is an ADD16ri or SUB16ri of SP 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::SP) 99 .addReg(MSP430::SP).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.getSubtarget().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 FP. 135 BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FP); 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 SP 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::SP).addReg(MSP430::FP); 158 if (CSSize) { 159 MachineInstr *MI = 160 BuildMI(MBB, MBBI, DL, 161 TII.get(MSP430::SUB16ri), MSP430::SP) 162 .addReg(MSP430::SP).addImm(CSSize); 163 // The SRW implicit def is dead. 164 MI->getOperand(3).setIsDead(); 165 } 166 } else { 167 // adjust stack pointer back: SP += numbytes 168 if (NumBytes) { 169 MachineInstr *MI = 170 BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP) 171 .addReg(MSP430::SP).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.getSubtarget().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 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.getSubtarget().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 MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr( 226 MachineFunction &MF, MachineBasicBlock &MBB, 227 MachineBasicBlock::iterator I) const { 228 const MSP430InstrInfo &TII = 229 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().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 SP, <amt>' and the 235 // adjcallstackdown instruction into 'add SP, <amt>' 236 // TODO: consider using push / pop instead of sub + store / add 237 MachineInstr &Old = *I; 238 uint64_t Amount = TII.getFrameSize(Old); 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 = 248 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP) 249 .addReg(MSP430::SP) 250 .addImm(Amount); 251 } else { 252 assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode()); 253 // factor out the amount the callee already popped. 254 Amount -= TII.getFramePoppedByCallee(Old); 255 if (Amount) 256 New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri), 257 MSP430::SP) 258 .addReg(MSP430::SP) 259 .addImm(Amount); 260 } 261 262 if (New) { 263 // The SRW implicit def is dead. 264 New->getOperand(3).setIsDead(); 265 266 // Replace the pseudo instruction with a new instruction... 267 MBB.insert(I, New); 268 } 269 } 270 } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 271 // If we are performing frame pointer elimination and if the callee pops 272 // something off the stack pointer, add it back. 273 if (uint64_t CalleeAmt = TII.getFramePoppedByCallee(*I)) { 274 MachineInstr &Old = *I; 275 MachineInstr *New = 276 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP) 277 .addReg(MSP430::SP) 278 .addImm(CalleeAmt); 279 // The SRW implicit def is dead. 280 New->getOperand(3).setIsDead(); 281 282 MBB.insert(I, New); 283 } 284 } 285 286 return MBB.erase(I); 287 } 288 289 void 290 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 291 RegScavenger *) const { 292 // Create a frame entry for the FP register that must be saved. 293 if (hasFP(MF)) { 294 int FrameIdx = MF.getFrameInfo().CreateFixedObject(2, -4, true); 295 (void)FrameIdx; 296 assert(FrameIdx == MF.getFrameInfo().getObjectIndexBegin() && 297 "Slot for FP register must be last in order to be found!"); 298 } 299 } 300