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