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/CFIInstBuilder.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/Target/TargetOptions.h" 23 24 using namespace llvm; 25 26 MSP430FrameLowering::MSP430FrameLowering(const MSP430Subtarget &STI) 27 : TargetFrameLowering(TargetFrameLowering::StackGrowsDown, Align(2), -2, 28 Align(2)), 29 STI(STI), TII(*STI.getInstrInfo()), TRI(STI.getRegisterInfo()) {} 30 31 bool MSP430FrameLowering::hasFPImpl(const MachineFunction &MF) const { 32 const MachineFrameInfo &MFI = MF.getFrameInfo(); 33 34 return (MF.getTarget().Options.DisableFramePointerElim(MF) || 35 MF.getFrameInfo().hasVarSizedObjects() || 36 MFI.isFrameAddressTaken()); 37 } 38 39 bool MSP430FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const { 40 return !MF.getFrameInfo().hasVarSizedObjects(); 41 } 42 43 void MSP430FrameLowering::BuildCFI(MachineBasicBlock &MBB, 44 MachineBasicBlock::iterator MBBI, 45 const DebugLoc &DL, 46 const MCCFIInstruction &CFIInst, 47 MachineInstr::MIFlag Flag) const { 48 MachineFunction &MF = *MBB.getParent(); 49 unsigned CFIIndex = MF.addFrameInst(CFIInst); 50 BuildMI(MBB, MBBI, DL, TII.get(TargetOpcode::CFI_INSTRUCTION)) 51 .addCFIIndex(CFIIndex) 52 .setMIFlag(Flag); 53 } 54 55 void MSP430FrameLowering::emitCalleeSavedFrameMoves( 56 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 57 const DebugLoc &DL, bool IsPrologue) const { 58 MachineFunction &MF = *MBB.getParent(); 59 MachineFrameInfo &MFI = MF.getFrameInfo(); 60 const MCRegisterInfo *MRI = MF.getContext().getRegisterInfo(); 61 62 // Add callee saved registers to move list. 63 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 64 65 // Calculate offsets. 66 for (const CalleeSavedInfo &I : CSI) { 67 int64_t Offset = MFI.getObjectOffset(I.getFrameIdx()); 68 MCRegister Reg = I.getReg(); 69 unsigned DwarfReg = MRI->getDwarfRegNum(Reg, true); 70 71 if (IsPrologue) { 72 BuildCFI(MBB, MBBI, DL, 73 MCCFIInstruction::createOffset(nullptr, DwarfReg, Offset)); 74 } else { 75 BuildCFI(MBB, MBBI, DL, 76 MCCFIInstruction::createRestore(nullptr, DwarfReg)); 77 } 78 } 79 } 80 81 void MSP430FrameLowering::emitPrologue(MachineFunction &MF, 82 MachineBasicBlock &MBB) const { 83 assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported"); 84 MachineFrameInfo &MFI = MF.getFrameInfo(); 85 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 86 const MSP430InstrInfo &TII = 87 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo()); 88 89 MachineBasicBlock::iterator MBBI = MBB.begin(); 90 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 91 92 // Get the number of bytes to allocate from the FrameInfo. 93 uint64_t StackSize = MFI.getStackSize(); 94 int stackGrowth = -2; 95 96 uint64_t NumBytes = 0; 97 if (hasFP(MF)) { 98 // Calculate required stack adjustment 99 uint64_t FrameSize = StackSize - 2; 100 NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize(); 101 102 // Get the offset of the stack slot for the EBP register... which is 103 // guaranteed to be the last slot by processFunctionBeforeFrameFinalized. 104 // Update the frame offset adjustment. 105 MFI.setOffsetAdjustment(-NumBytes); 106 107 // Save FP into the appropriate stack slot... 108 BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r)) 109 .addReg(MSP430::R4, RegState::Kill) 110 .setMIFlag(MachineInstr::FrameSetup); 111 112 // Mark the place where FP was saved. 113 // Define the current CFA rule to use the provided offset. 114 BuildCFI(MBB, MBBI, DL, 115 MCCFIInstruction::cfiDefCfaOffset(nullptr, -2 * stackGrowth), 116 MachineInstr::FrameSetup); 117 118 // Change the rule for the FramePtr to be an "offset" rule. 119 unsigned DwarfFramePtr = TRI->getDwarfRegNum(MSP430::R4, true); 120 BuildCFI( 121 MBB, MBBI, DL, 122 MCCFIInstruction::createOffset(nullptr, DwarfFramePtr, 2 * stackGrowth), 123 MachineInstr::FrameSetup); 124 125 // Update FP with the new base value... 126 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::R4) 127 .addReg(MSP430::SP) 128 .setMIFlag(MachineInstr::FrameSetup); 129 130 // Mark effective beginning of when frame pointer becomes valid. 131 // Define the current CFA to use the FP register. 132 BuildCFI(MBB, MBBI, DL, 133 MCCFIInstruction::createDefCfaRegister(nullptr, DwarfFramePtr), 134 MachineInstr::FrameSetup); 135 136 // Mark the FramePtr as live-in in every block except the entry. 137 for (MachineBasicBlock &MBBJ : llvm::drop_begin(MF)) 138 MBBJ.addLiveIn(MSP430::R4); 139 } else 140 NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize(); 141 142 // Skip the callee-saved push instructions. 143 int StackOffset = 2 * stackGrowth; 144 while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup) && 145 (MBBI->getOpcode() == MSP430::PUSH16r)) { 146 ++MBBI; 147 148 if (!hasFP(MF)) { 149 // Mark callee-saved push instruction. 150 // Define the current CFA rule to use the provided offset. 151 assert(StackSize && "Expected stack frame"); 152 BuildCFI(MBB, MBBI, DL, 153 MCCFIInstruction::cfiDefCfaOffset(nullptr, -StackOffset), 154 MachineInstr::FrameSetup); 155 StackOffset += stackGrowth; 156 } 157 } 158 159 if (MBBI != MBB.end()) 160 DL = MBBI->getDebugLoc(); 161 162 if (NumBytes) { // adjust stack pointer: SP -= numbytes 163 // If there is an SUB16ri of SP immediately before this instruction, merge 164 // the two. 165 //NumBytes -= mergeSPUpdates(MBB, MBBI, true); 166 // If there is an ADD16ri or SUB16ri of SP immediately after this 167 // instruction, merge the two instructions. 168 // mergeSPUpdatesDown(MBB, MBBI, &NumBytes); 169 170 if (NumBytes) { 171 MachineInstr *MI = 172 BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP) 173 .addReg(MSP430::SP) 174 .addImm(NumBytes) 175 .setMIFlag(MachineInstr::FrameSetup); 176 // The SRW implicit def is dead. 177 MI->getOperand(3).setIsDead(); 178 } 179 if (!hasFP(MF)) { 180 // Adjust the previous CFA value if CFA was not redefined by FP 181 BuildCFI( 182 MBB, MBBI, DL, 183 MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize - stackGrowth), 184 MachineInstr::FrameSetup); 185 } 186 } 187 188 emitCalleeSavedFrameMoves(MBB, MBBI, DL, true); 189 } 190 191 void MSP430FrameLowering::emitEpilogue(MachineFunction &MF, 192 MachineBasicBlock &MBB) const { 193 const MachineFrameInfo &MFI = MF.getFrameInfo(); 194 MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>(); 195 const MSP430InstrInfo &TII = 196 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo()); 197 198 MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr(); 199 unsigned RetOpcode = MBBI->getOpcode(); 200 DebugLoc DL = MBBI->getDebugLoc(); 201 202 switch (RetOpcode) { 203 case MSP430::RET: 204 case MSP430::RETI: break; // These are ok 205 default: 206 llvm_unreachable("Can only insert epilog into returning blocks"); 207 } 208 209 // Get the number of bytes to allocate from the FrameInfo 210 uint64_t StackSize = MFI.getStackSize(); 211 unsigned CSSize = MSP430FI->getCalleeSavedFrameSize(); 212 uint64_t NumBytes = 0; 213 214 MachineBasicBlock::iterator AfterPop = MBBI; 215 if (hasFP(MF)) { 216 // Calculate required stack adjustment 217 uint64_t FrameSize = StackSize - 2; 218 NumBytes = FrameSize - CSSize; 219 220 // pop FP. 221 BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::R4) 222 .setMIFlag(MachineInstr::FrameDestroy); 223 unsigned DwarfStackPtr = TRI->getDwarfRegNum(MSP430::SP, true); 224 BuildCFI(MBB, MBBI, DL, 225 MCCFIInstruction::cfiDefCfa(nullptr, DwarfStackPtr, 2), 226 MachineInstr::FrameDestroy); 227 --MBBI; 228 if (!MBB.succ_empty() && !MBB.isReturnBlock()) { 229 unsigned DwarfFramePtr = TRI->getDwarfRegNum(MSP430::R4, true); 230 BuildCFI(MBB, AfterPop, DL, 231 MCCFIInstruction::createRestore(nullptr, DwarfFramePtr), 232 MachineInstr::FrameDestroy); 233 --MBBI; 234 --AfterPop; 235 } 236 } else 237 NumBytes = StackSize - CSSize; 238 239 // Skip the callee-saved pop instructions. 240 MachineBasicBlock::iterator FirstCSPop = MBBI; 241 while (MBBI != MBB.begin()) { 242 MachineBasicBlock::iterator PI = std::prev(MBBI); 243 unsigned Opc = PI->getOpcode(); 244 if ((Opc != MSP430::POP16r || !PI->getFlag(MachineInstr::FrameDestroy)) && 245 !PI->isTerminator()) 246 break; 247 FirstCSPop = PI; 248 --MBBI; 249 } 250 MBBI = FirstCSPop; 251 252 DL = MBBI->getDebugLoc(); 253 254 // If there is an ADD16ri or SUB16ri of SP immediately before this 255 // instruction, merge the two instructions. 256 //if (NumBytes || MFI.hasVarSizedObjects()) 257 // mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes); 258 259 if (MFI.hasVarSizedObjects()) { 260 BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::SP) 261 .addReg(MSP430::R4) 262 .setMIFlag(MachineInstr::FrameDestroy); 263 if (CSSize) { 264 MachineInstr *MI = 265 BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SP) 266 .addReg(MSP430::SP) 267 .addImm(CSSize) 268 .setMIFlag(MachineInstr::FrameDestroy); 269 // The SRW implicit def is dead. 270 MI->getOperand(3).setIsDead(); 271 } 272 } else { 273 // adjust stack pointer back: SP += numbytes 274 if (NumBytes) { 275 MachineInstr *MI = 276 BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SP) 277 .addReg(MSP430::SP) 278 .addImm(NumBytes) 279 .setMIFlag(MachineInstr::FrameDestroy); 280 // The SRW implicit def is dead. 281 MI->getOperand(3).setIsDead(); 282 283 if (!hasFP(MF)) { 284 // Adjust CFA value if it was defined by SP 285 BuildCFI(MBB, MBBI, DL, 286 MCCFIInstruction::cfiDefCfaOffset(nullptr, CSSize + 2), 287 MachineInstr::FrameDestroy); 288 } 289 } 290 } 291 292 if (!hasFP(MF)) { 293 MBBI = FirstCSPop; 294 int64_t Offset = -(int64_t)CSSize - 2; 295 // Mark callee-saved pop instruction. 296 // Define the current CFA rule to use the provided offset. 297 while (MBBI != MBB.end()) { 298 MachineBasicBlock::iterator PI = MBBI; 299 unsigned Opc = PI->getOpcode(); 300 ++MBBI; 301 if (Opc == MSP430::POP16r) { 302 Offset += 2; 303 BuildCFI(MBB, MBBI, DL, 304 MCCFIInstruction::cfiDefCfaOffset(nullptr, -Offset), 305 MachineInstr::FrameDestroy); 306 } 307 } 308 } 309 emitCalleeSavedFrameMoves(MBB, AfterPop, DL, false); 310 } 311 312 // FIXME: Can we eleminate these in favour of generic code? 313 bool MSP430FrameLowering::spillCalleeSavedRegisters( 314 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 315 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 316 if (CSI.empty()) 317 return false; 318 319 DebugLoc DL; 320 if (MI != MBB.end()) DL = MI->getDebugLoc(); 321 322 MachineFunction &MF = *MBB.getParent(); 323 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 324 MSP430MachineFunctionInfo *MFI = MF.getInfo<MSP430MachineFunctionInfo>(); 325 MFI->setCalleeSavedFrameSize(CSI.size() * 2); 326 327 for (const CalleeSavedInfo &I : CSI) { 328 MCRegister Reg = I.getReg(); 329 // Add the callee-saved register as live-in. It's killed at the spill. 330 MBB.addLiveIn(Reg); 331 BuildMI(MBB, MI, DL, TII.get(MSP430::PUSH16r)) 332 .addReg(Reg, RegState::Kill) 333 .setMIFlag(MachineInstr::FrameSetup); 334 } 335 return true; 336 } 337 338 bool MSP430FrameLowering::restoreCalleeSavedRegisters( 339 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 340 MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 341 if (CSI.empty()) 342 return false; 343 344 DebugLoc DL; 345 if (MI != MBB.end()) DL = MI->getDebugLoc(); 346 347 MachineFunction &MF = *MBB.getParent(); 348 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 349 350 for (const CalleeSavedInfo &I : llvm::reverse(CSI)) 351 BuildMI(MBB, MI, DL, TII.get(MSP430::POP16r), I.getReg()) 352 .setMIFlag(MachineInstr::FrameDestroy); 353 354 return true; 355 } 356 357 MachineBasicBlock::iterator MSP430FrameLowering::eliminateCallFramePseudoInstr( 358 MachineFunction &MF, MachineBasicBlock &MBB, 359 MachineBasicBlock::iterator I) const { 360 const MSP430InstrInfo &TII = 361 *static_cast<const MSP430InstrInfo *>(MF.getSubtarget().getInstrInfo()); 362 if (!hasReservedCallFrame(MF)) { 363 // If the stack pointer can be changed after prologue, turn the 364 // adjcallstackup instruction into a 'sub SP, <amt>' and the 365 // adjcallstackdown instruction into 'add SP, <amt>' 366 // TODO: consider using push / pop instead of sub + store / add 367 MachineInstr &Old = *I; 368 uint64_t Amount = TII.getFrameSize(Old); 369 if (Amount != 0) { 370 // We need to keep the stack aligned properly. To do this, we round the 371 // amount of space needed for the outgoing arguments up to the next 372 // alignment boundary. 373 Amount = alignTo(Amount, getStackAlign()); 374 375 MachineInstr *New = nullptr; 376 if (Old.getOpcode() == TII.getCallFrameSetupOpcode()) { 377 New = 378 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP) 379 .addReg(MSP430::SP) 380 .addImm(Amount); 381 } else { 382 assert(Old.getOpcode() == TII.getCallFrameDestroyOpcode()); 383 // factor out the amount the callee already popped. 384 Amount -= TII.getFramePoppedByCallee(Old); 385 if (Amount) 386 New = BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::ADD16ri), 387 MSP430::SP) 388 .addReg(MSP430::SP) 389 .addImm(Amount); 390 } 391 392 if (New) { 393 // The SRW implicit def is dead. 394 New->getOperand(3).setIsDead(); 395 396 // Replace the pseudo instruction with a new instruction... 397 MBB.insert(I, New); 398 } 399 } 400 } else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) { 401 // If we are performing frame pointer elimination and if the callee pops 402 // something off the stack pointer, add it back. 403 if (uint64_t CalleeAmt = TII.getFramePoppedByCallee(*I)) { 404 MachineInstr &Old = *I; 405 MachineInstr *New = 406 BuildMI(MF, Old.getDebugLoc(), TII.get(MSP430::SUB16ri), MSP430::SP) 407 .addReg(MSP430::SP) 408 .addImm(CalleeAmt); 409 if (!hasFP(MF)) { 410 CFIInstBuilder(MBB, I, MachineInstr::NoFlags) 411 .buildAdjustCFAOffset(CalleeAmt); 412 } 413 // The SRW implicit def is dead. 414 New->getOperand(3).setIsDead(); 415 416 MBB.insert(I, New); 417 } 418 } 419 420 return MBB.erase(I); 421 } 422 423 void 424 MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF, 425 RegScavenger *) const { 426 // Create a frame entry for the FP register that must be saved. 427 if (hasFP(MF)) { 428 int FrameIdx = MF.getFrameInfo().CreateFixedObject(2, -4, true); 429 (void)FrameIdx; 430 assert(FrameIdx == MF.getFrameInfo().getObjectIndexBegin() && 431 "Slot for FP register must be last in order to be found!"); 432 } 433 } 434