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