1 //===-- LoongArchFrameLowering.cpp - LoongArch Frame Information -*- C++ -*-==// 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 LoongArch implementation of TargetFrameLowering class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "LoongArchFrameLowering.h" 14 #include "LoongArchMachineFunctionInfo.h" 15 #include "LoongArchSubtarget.h" 16 #include "MCTargetDesc/LoongArchBaseInfo.h" 17 #include "MCTargetDesc/LoongArchMCTargetDesc.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/CodeGen/RegisterScavenging.h" 23 #include "llvm/IR/DiagnosticInfo.h" 24 #include "llvm/MC/MCDwarf.h" 25 26 using namespace llvm; 27 28 #define DEBUG_TYPE "loongarch-frame-lowering" 29 30 // Return true if the specified function should have a dedicated frame 31 // pointer register. This is true if frame pointer elimination is 32 // disabled, if it needs dynamic stack realignment, if the function has 33 // variable sized allocas, or if the frame address is taken. 34 bool LoongArchFrameLowering::hasFP(const MachineFunction &MF) const { 35 const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo(); 36 37 const MachineFrameInfo &MFI = MF.getFrameInfo(); 38 return MF.getTarget().Options.DisableFramePointerElim(MF) || 39 RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() || 40 MFI.isFrameAddressTaken(); 41 } 42 43 bool LoongArchFrameLowering::hasBP(const MachineFunction &MF) const { 44 const MachineFrameInfo &MFI = MF.getFrameInfo(); 45 const TargetRegisterInfo *TRI = STI.getRegisterInfo(); 46 47 return MFI.hasVarSizedObjects() && TRI->hasStackRealignment(MF); 48 } 49 50 void LoongArchFrameLowering::adjustReg(MachineBasicBlock &MBB, 51 MachineBasicBlock::iterator MBBI, 52 const DebugLoc &DL, Register DestReg, 53 Register SrcReg, int64_t Val, 54 MachineInstr::MIFlag Flag) const { 55 const LoongArchInstrInfo *TII = STI.getInstrInfo(); 56 bool IsLA64 = STI.is64Bit(); 57 unsigned Addi = IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W; 58 59 if (DestReg == SrcReg && Val == 0) 60 return; 61 62 if (isInt<12>(Val)) { 63 // addi.w/d $DstReg, $SrcReg, Val 64 BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) 65 .addReg(SrcReg) 66 .addImm(Val) 67 .setMIFlag(Flag); 68 return; 69 } 70 71 // Try to split the offset across two ADDIs. We need to keep the stack pointer 72 // aligned after each ADDI. We need to determine the maximum value we can put 73 // in each ADDI. In the negative direction, we can use -2048 which is always 74 // sufficiently aligned. In the positive direction, we need to find the 75 // largest 12-bit immediate that is aligned. Exclude -4096 since it can be 76 // created with LU12I.W. 77 assert(getStackAlign().value() < 2048 && "Stack alignment too large"); 78 int64_t MaxPosAdjStep = 2048 - getStackAlign().value(); 79 if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) { 80 int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep; 81 Val -= FirstAdj; 82 BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) 83 .addReg(SrcReg) 84 .addImm(FirstAdj) 85 .setMIFlag(Flag); 86 BuildMI(MBB, MBBI, DL, TII->get(Addi), DestReg) 87 .addReg(DestReg, RegState::Kill) 88 .addImm(Val) 89 .setMIFlag(Flag); 90 return; 91 } 92 93 unsigned Opc = IsLA64 ? LoongArch::ADD_D : LoongArch::ADD_W; 94 if (Val < 0) { 95 Val = -Val; 96 Opc = IsLA64 ? LoongArch::SUB_D : LoongArch::SUB_W; 97 } 98 99 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 100 Register ScratchReg = MRI.createVirtualRegister(&LoongArch::GPRRegClass); 101 TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag); 102 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 103 .addReg(SrcReg) 104 .addReg(ScratchReg, RegState::Kill) 105 .setMIFlag(Flag); 106 } 107 108 // Determine the size of the frame and maximum call frame size. 109 void LoongArchFrameLowering::determineFrameLayout(MachineFunction &MF) const { 110 MachineFrameInfo &MFI = MF.getFrameInfo(); 111 112 // Get the number of bytes to allocate from the FrameInfo. 113 uint64_t FrameSize = MFI.getStackSize(); 114 115 // Make sure the frame is aligned. 116 FrameSize = alignTo(FrameSize, getStackAlign()); 117 118 // Update frame info. 119 MFI.setStackSize(FrameSize); 120 } 121 122 static uint64_t estimateFunctionSizeInBytes(const LoongArchInstrInfo *TII, 123 const MachineFunction &MF) { 124 uint64_t FuncSize = 0; 125 for (auto &MBB : MF) 126 for (auto &MI : MBB) 127 FuncSize += TII->getInstSizeInBytes(MI); 128 return FuncSize; 129 } 130 131 static bool needScavSlotForCFR(MachineFunction &MF) { 132 if (!MF.getSubtarget<LoongArchSubtarget>().hasBasicF()) 133 return false; 134 for (auto &MBB : MF) 135 for (auto &MI : MBB) 136 if (MI.getOpcode() == LoongArch::PseudoST_CFR) 137 return true; 138 return false; 139 } 140 141 void LoongArchFrameLowering::processFunctionBeforeFrameFinalized( 142 MachineFunction &MF, RegScavenger *RS) const { 143 const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); 144 const TargetRegisterClass &RC = LoongArch::GPRRegClass; 145 const LoongArchInstrInfo *TII = STI.getInstrInfo(); 146 LoongArchMachineFunctionInfo *LAFI = 147 MF.getInfo<LoongArchMachineFunctionInfo>(); 148 MachineFrameInfo &MFI = MF.getFrameInfo(); 149 150 unsigned ScavSlotsNum = 0; 151 152 // Far branches beyond 27-bit offset require a spill slot for scratch register. 153 bool IsLargeFunction = !isInt<27>(estimateFunctionSizeInBytes(TII, MF)); 154 if (IsLargeFunction) 155 ScavSlotsNum = 1; 156 157 // estimateStackSize has been observed to under-estimate the final stack 158 // size, so give ourselves wiggle-room by checking for stack size 159 // representable an 11-bit signed field rather than 12-bits. 160 if (!isInt<11>(MFI.estimateStackSize(MF))) 161 ScavSlotsNum = std::max(ScavSlotsNum, 1u); 162 163 // For CFR spill. 164 if (needScavSlotForCFR(MF)) 165 ++ScavSlotsNum; 166 167 // Create emergency spill slots. 168 for (unsigned i = 0; i < ScavSlotsNum; ++i) { 169 int FI = MFI.CreateStackObject(RI->getSpillSize(RC), RI->getSpillAlign(RC), 170 false); 171 RS->addScavengingFrameIndex(FI); 172 if (IsLargeFunction && LAFI->getBranchRelaxationSpillFrameIndex() == -1) 173 LAFI->setBranchRelaxationSpillFrameIndex(FI); 174 LLVM_DEBUG(dbgs() << "Allocated FI(" << FI 175 << ") as the emergency spill slot.\n"); 176 } 177 } 178 179 void LoongArchFrameLowering::emitPrologue(MachineFunction &MF, 180 MachineBasicBlock &MBB) const { 181 MachineFrameInfo &MFI = MF.getFrameInfo(); 182 auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>(); 183 const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); 184 const LoongArchInstrInfo *TII = STI.getInstrInfo(); 185 MachineBasicBlock::iterator MBBI = MBB.begin(); 186 bool IsLA64 = STI.is64Bit(); 187 188 Register SPReg = LoongArch::R3; 189 Register FPReg = LoongArch::R22; 190 191 // Debug location must be unknown since the first debug location is used 192 // to determine the end of the prologue. 193 DebugLoc DL; 194 // All calls are tail calls in GHC calling conv, and functions have no 195 // prologue/epilogue. 196 if (MF.getFunction().getCallingConv() == CallingConv::GHC) 197 return; 198 // Determine the correct frame layout 199 determineFrameLayout(MF); 200 201 // First, compute final stack size. 202 uint64_t StackSize = MFI.getStackSize(); 203 uint64_t RealStackSize = StackSize; 204 205 // Early exit if there is no need to allocate space in the stack. 206 if (StackSize == 0 && !MFI.adjustsStack()) 207 return; 208 209 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF, true); 210 uint64_t SecondSPAdjustAmount = RealStackSize - FirstSPAdjustAmount; 211 // Split the SP adjustment to reduce the offsets of callee saved spill. 212 if (FirstSPAdjustAmount) 213 StackSize = FirstSPAdjustAmount; 214 215 // Adjust stack. 216 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -StackSize, MachineInstr::FrameSetup); 217 if (FirstSPAdjustAmount != 2048 || SecondSPAdjustAmount == 0) { 218 // Emit ".cfi_def_cfa_offset StackSize". 219 unsigned CFIIndex = 220 MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, StackSize)); 221 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 222 .addCFIIndex(CFIIndex) 223 .setMIFlag(MachineInstr::FrameSetup); 224 } 225 226 const auto &CSI = MFI.getCalleeSavedInfo(); 227 228 // The frame pointer is callee-saved, and code has been generated for us to 229 // save it to the stack. We need to skip over the storing of callee-saved 230 // registers as the frame pointer must be modified after it has been saved 231 // to the stack, not before. 232 std::advance(MBBI, CSI.size()); 233 234 // Iterate over list of callee-saved registers and emit .cfi_offset 235 // directives. 236 for (const auto &Entry : CSI) { 237 int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx()); 238 unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset( 239 nullptr, RI->getDwarfRegNum(Entry.getReg(), true), Offset)); 240 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 241 .addCFIIndex(CFIIndex) 242 .setMIFlag(MachineInstr::FrameSetup); 243 } 244 245 // Generate new FP. 246 if (hasFP(MF)) { 247 adjustReg(MBB, MBBI, DL, FPReg, SPReg, 248 StackSize - LoongArchFI->getVarArgsSaveSize(), 249 MachineInstr::FrameSetup); 250 251 // Emit ".cfi_def_cfa $fp, LoongArchFI->getVarArgsSaveSize()" 252 unsigned CFIIndex = MF.addFrameInst( 253 MCCFIInstruction::cfiDefCfa(nullptr, RI->getDwarfRegNum(FPReg, true), 254 LoongArchFI->getVarArgsSaveSize())); 255 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 256 .addCFIIndex(CFIIndex) 257 .setMIFlag(MachineInstr::FrameSetup); 258 } 259 260 // Emit the second SP adjustment after saving callee saved registers. 261 if (FirstSPAdjustAmount && SecondSPAdjustAmount) { 262 if (hasFP(MF)) { 263 assert(SecondSPAdjustAmount > 0 && 264 "SecondSPAdjustAmount should be greater than zero"); 265 adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount, 266 MachineInstr::FrameSetup); 267 } else { 268 // FIXME: RegScavenger will place the spill instruction before the 269 // prologue if a VReg is created in the prologue. This will pollute the 270 // caller's stack data. Therefore, until there is better way, we just use 271 // the `addi.w/d` instruction for stack adjustment to ensure that VReg 272 // will not be created. 273 for (int Val = SecondSPAdjustAmount; Val > 0; Val -= 2048) 274 BuildMI(MBB, MBBI, DL, 275 TII->get(IsLA64 ? LoongArch::ADDI_D : LoongArch::ADDI_W), SPReg) 276 .addReg(SPReg) 277 .addImm(Val < 2048 ? -Val : -2048) 278 .setMIFlag(MachineInstr::FrameSetup); 279 280 // If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0", 281 // don't emit an sp-based .cfi_def_cfa_offset 282 // Emit ".cfi_def_cfa_offset RealStackSize" 283 unsigned CFIIndex = MF.addFrameInst( 284 MCCFIInstruction::cfiDefCfaOffset(nullptr, RealStackSize)); 285 BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION)) 286 .addCFIIndex(CFIIndex) 287 .setMIFlag(MachineInstr::FrameSetup); 288 } 289 } 290 291 if (hasFP(MF)) { 292 // Realign stack. 293 if (RI->hasStackRealignment(MF)) { 294 unsigned ShiftAmount = Log2(MFI.getMaxAlign()); 295 Register VR = 296 MF.getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); 297 BuildMI(MBB, MBBI, DL, 298 TII->get(IsLA64 ? LoongArch::SRLI_D : LoongArch::SRLI_W), VR) 299 .addReg(SPReg) 300 .addImm(ShiftAmount) 301 .setMIFlag(MachineInstr::FrameSetup); 302 BuildMI(MBB, MBBI, DL, 303 TII->get(IsLA64 ? LoongArch::SLLI_D : LoongArch::SLLI_W), SPReg) 304 .addReg(VR) 305 .addImm(ShiftAmount) 306 .setMIFlag(MachineInstr::FrameSetup); 307 // FP will be used to restore the frame in the epilogue, so we need 308 // another base register BP to record SP after re-alignment. SP will 309 // track the current stack after allocating variable sized objects. 310 if (hasBP(MF)) { 311 // move BP, $sp 312 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::OR), 313 LoongArchABI::getBPReg()) 314 .addReg(SPReg) 315 .addReg(LoongArch::R0) 316 .setMIFlag(MachineInstr::FrameSetup); 317 } 318 } 319 } 320 } 321 322 void LoongArchFrameLowering::emitEpilogue(MachineFunction &MF, 323 MachineBasicBlock &MBB) const { 324 const LoongArchRegisterInfo *RI = STI.getRegisterInfo(); 325 MachineFrameInfo &MFI = MF.getFrameInfo(); 326 auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>(); 327 Register SPReg = LoongArch::R3; 328 // All calls are tail calls in GHC calling conv, and functions have no 329 // prologue/epilogue. 330 if (MF.getFunction().getCallingConv() == CallingConv::GHC) 331 return; 332 MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator(); 333 DebugLoc DL = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc(); 334 335 const auto &CSI = MFI.getCalleeSavedInfo(); 336 // Skip to before the restores of callee-saved registers. 337 auto LastFrameDestroy = MBBI; 338 if (!CSI.empty()) 339 LastFrameDestroy = std::prev(MBBI, CSI.size()); 340 341 // Get the number of bytes from FrameInfo. 342 uint64_t StackSize = MFI.getStackSize(); 343 344 // Restore the stack pointer. 345 if (RI->hasStackRealignment(MF) || MFI.hasVarSizedObjects()) { 346 assert(hasFP(MF) && "frame pointer should not have been eliminated"); 347 adjustReg(MBB, LastFrameDestroy, DL, SPReg, LoongArch::R22, 348 -StackSize + LoongArchFI->getVarArgsSaveSize(), 349 MachineInstr::FrameDestroy); 350 } 351 352 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); 353 if (FirstSPAdjustAmount) { 354 uint64_t SecondSPAdjustAmount = StackSize - FirstSPAdjustAmount; 355 assert(SecondSPAdjustAmount > 0 && 356 "SecondSPAdjustAmount should be greater than zero"); 357 358 adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount, 359 MachineInstr::FrameDestroy); 360 StackSize = FirstSPAdjustAmount; 361 } 362 363 // Deallocate stack 364 adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy); 365 } 366 367 // We would like to split the SP adjustment to reduce prologue/epilogue 368 // as following instructions. In this way, the offset of the callee saved 369 // register could fit in a single store. 370 // e.g. 371 // addi.d $sp, $sp, -2032 372 // st.d $ra, $sp, 2024 373 // st.d $fp, $sp, 2016 374 // addi.d $sp, $sp, -16 375 uint64_t 376 LoongArchFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF, 377 bool IsPrologue) const { 378 const MachineFrameInfo &MFI = MF.getFrameInfo(); 379 const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); 380 381 // Return the FirstSPAdjustAmount if the StackSize can not fit in a signed 382 // 12-bit and there exists a callee-saved register needing to be pushed. 383 if (!isInt<12>(MFI.getStackSize())) { 384 // FirstSPAdjustAmount is chosen as (2048 - StackAlign) because 2048 will 385 // cause sp = sp + 2048 in the epilogue to be split into multiple 386 // instructions. Offsets smaller than 2048 can fit in a single load/store 387 // instruction, and we have to stick with the stack alignment. 388 // So (2048 - StackAlign) will satisfy the stack alignment. 389 // 390 // FIXME: This place may seem odd. When using multiple ADDI instructions to 391 // adjust the stack in Prologue, and there are no callee-saved registers, we 392 // can take advantage of the logic of split sp ajustment to reduce code 393 // changes. 394 return CSI.size() > 0 ? 2048 - getStackAlign().value() 395 : (IsPrologue ? 2048 : 0); 396 } 397 return 0; 398 } 399 400 void LoongArchFrameLowering::determineCalleeSaves(MachineFunction &MF, 401 BitVector &SavedRegs, 402 RegScavenger *RS) const { 403 TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS); 404 // Unconditionally spill RA and FP only if the function uses a frame 405 // pointer. 406 if (hasFP(MF)) { 407 SavedRegs.set(LoongArch::R1); 408 SavedRegs.set(LoongArch::R22); 409 } 410 // Mark BP as used if function has dedicated base pointer. 411 if (hasBP(MF)) 412 SavedRegs.set(LoongArchABI::getBPReg()); 413 } 414 415 // Do not preserve stack space within prologue for outgoing variables if the 416 // function contains variable size objects. 417 // Let eliminateCallFramePseudoInstr preserve stack space for it. 418 bool LoongArchFrameLowering::hasReservedCallFrame( 419 const MachineFunction &MF) const { 420 return !MF.getFrameInfo().hasVarSizedObjects(); 421 } 422 423 // Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions. 424 MachineBasicBlock::iterator 425 LoongArchFrameLowering::eliminateCallFramePseudoInstr( 426 MachineFunction &MF, MachineBasicBlock &MBB, 427 MachineBasicBlock::iterator MI) const { 428 Register SPReg = LoongArch::R3; 429 DebugLoc DL = MI->getDebugLoc(); 430 431 if (!hasReservedCallFrame(MF)) { 432 // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and 433 // ADJCALLSTACKUP must be converted to instructions manipulating the stack 434 // pointer. This is necessary when there is a variable length stack 435 // allocation (e.g. alloca), which means it's not possible to allocate 436 // space for outgoing arguments from within the function prologue. 437 int64_t Amount = MI->getOperand(0).getImm(); 438 439 if (Amount != 0) { 440 // Ensure the stack remains aligned after adjustment. 441 Amount = alignSPAdjust(Amount); 442 443 if (MI->getOpcode() == LoongArch::ADJCALLSTACKDOWN) 444 Amount = -Amount; 445 446 adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags); 447 } 448 } 449 450 return MBB.erase(MI); 451 } 452 453 bool LoongArchFrameLowering::spillCalleeSavedRegisters( 454 MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 455 ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const { 456 if (CSI.empty()) 457 return true; 458 459 MachineFunction *MF = MBB.getParent(); 460 const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo(); 461 462 // Insert the spill to the stack frame. 463 for (auto &CS : CSI) { 464 Register Reg = CS.getReg(); 465 // If the register is RA and the return address is taken by method 466 // LoongArchTargetLowering::lowerRETURNADDR, don't set kill flag. 467 bool IsKill = 468 !(Reg == LoongArch::R1 && MF->getFrameInfo().isReturnAddressTaken()); 469 const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg); 470 TII.storeRegToStackSlot(MBB, MI, Reg, IsKill, CS.getFrameIdx(), RC, TRI, 471 Register()); 472 } 473 474 return true; 475 } 476 477 StackOffset LoongArchFrameLowering::getFrameIndexReference( 478 const MachineFunction &MF, int FI, Register &FrameReg) const { 479 const MachineFrameInfo &MFI = MF.getFrameInfo(); 480 const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo(); 481 auto *LoongArchFI = MF.getInfo<LoongArchMachineFunctionInfo>(); 482 uint64_t StackSize = MFI.getStackSize(); 483 uint64_t FirstSPAdjustAmount = getFirstSPAdjustAmount(MF); 484 485 // Callee-saved registers should be referenced relative to the stack 486 // pointer (positive offset), otherwise use the frame pointer (negative 487 // offset). 488 const auto &CSI = MFI.getCalleeSavedInfo(); 489 int MinCSFI = 0; 490 int MaxCSFI = -1; 491 StackOffset Offset = 492 StackOffset::getFixed(MFI.getObjectOffset(FI) - getOffsetOfLocalArea() + 493 MFI.getOffsetAdjustment()); 494 495 if (CSI.size()) { 496 MinCSFI = CSI[0].getFrameIdx(); 497 MaxCSFI = CSI[CSI.size() - 1].getFrameIdx(); 498 } 499 500 if (FI >= MinCSFI && FI <= MaxCSFI) { 501 FrameReg = LoongArch::R3; 502 if (FirstSPAdjustAmount) 503 Offset += StackOffset::getFixed(FirstSPAdjustAmount); 504 else 505 Offset += StackOffset::getFixed(StackSize); 506 } else if (RI->hasStackRealignment(MF) && !MFI.isFixedObjectIndex(FI)) { 507 // If the stack was realigned, the frame pointer is set in order to allow 508 // SP to be restored, so we need another base register to record the stack 509 // after realignment. 510 FrameReg = hasBP(MF) ? LoongArchABI::getBPReg() : LoongArch::R3; 511 Offset += StackOffset::getFixed(StackSize); 512 } else { 513 FrameReg = RI->getFrameRegister(MF); 514 if (hasFP(MF)) 515 Offset += StackOffset::getFixed(LoongArchFI->getVarArgsSaveSize()); 516 else 517 Offset += StackOffset::getFixed(StackSize); 518 } 519 520 return Offset; 521 } 522