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