Path: blob/main/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYFrameLowering.cpp
35266 views
//===-- CSKYFrameLowering.cpp - CSKY Frame Information ------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the CSKY implementation of TargetFrameLowering class.9//10//===----------------------------------------------------------------------===//1112#include "CSKYFrameLowering.h"13#include "CSKYMachineFunctionInfo.h"14#include "CSKYSubtarget.h"15#include "llvm/CodeGen/MachineConstantPool.h"16#include "llvm/CodeGen/MachineFrameInfo.h"17#include "llvm/CodeGen/MachineFunction.h"18#include "llvm/CodeGen/MachineInstrBuilder.h"19#include "llvm/CodeGen/MachineRegisterInfo.h"20#include "llvm/CodeGen/RegisterScavenging.h"21#include "llvm/IR/DiagnosticInfo.h"22#include "llvm/MC/MCDwarf.h"2324using namespace llvm;2526#define DEBUG_TYPE "csky-frame-lowering"2728// Returns the register used to hold the frame pointer.29static Register getFPReg(const CSKYSubtarget &STI) { return CSKY::R8; }3031// To avoid the BP value clobbered by a function call, we need to choose a32// callee saved register to save the value.33static Register getBPReg(const CSKYSubtarget &STI) { return CSKY::R7; }3435bool CSKYFrameLowering::hasFP(const MachineFunction &MF) const {36const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();3738const MachineFrameInfo &MFI = MF.getFrameInfo();39return MF.getTarget().Options.DisableFramePointerElim(MF) ||40RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||41MFI.isFrameAddressTaken();42}4344bool CSKYFrameLowering::hasBP(const MachineFunction &MF) const {45const MachineFrameInfo &MFI = MF.getFrameInfo();4647return MFI.hasVarSizedObjects();48}4950// Determines the size of the frame and maximum call frame size.51void CSKYFrameLowering::determineFrameLayout(MachineFunction &MF) const {52MachineFrameInfo &MFI = MF.getFrameInfo();53const CSKYRegisterInfo *RI = STI.getRegisterInfo();5455// Get the number of bytes to allocate from the FrameInfo.56uint64_t FrameSize = MFI.getStackSize();5758// Get the alignment.59Align StackAlign = getStackAlign();60if (RI->hasStackRealignment(MF)) {61Align MaxStackAlign = std::max(StackAlign, MFI.getMaxAlign());62FrameSize += (MaxStackAlign.value() - StackAlign.value());63StackAlign = MaxStackAlign;64}6566// Set Max Call Frame Size67uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign);68MFI.setMaxCallFrameSize(MaxCallSize);6970// Make sure the frame is aligned.71FrameSize = alignTo(FrameSize, StackAlign);7273// Update frame info.74MFI.setStackSize(FrameSize);75}7677void CSKYFrameLowering::emitPrologue(MachineFunction &MF,78MachineBasicBlock &MBB) const {79CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();80MachineFrameInfo &MFI = MF.getFrameInfo();81const CSKYRegisterInfo *RI = STI.getRegisterInfo();82const CSKYInstrInfo *TII = STI.getInstrInfo();83MachineBasicBlock::iterator MBBI = MBB.begin();84const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();85const MachineRegisterInfo &MRI = MF.getRegInfo();8687Register FPReg = getFPReg(STI);88Register SPReg = CSKY::R14;89Register BPReg = getBPReg(STI);9091// Debug location must be unknown since the first debug location is used92// to determine the end of the prologue.93DebugLoc DL;9495if (MF.getFunction().hasFnAttribute("interrupt"))96BuildMI(MBB, MBBI, DL, TII->get(CSKY::NIE));9798// Determine the correct frame layout99determineFrameLayout(MF);100101// FIXME (note copied from Lanai): This appears to be overallocating. Needs102// investigation. Get the number of bytes to allocate from the FrameInfo.103uint64_t StackSize = MFI.getStackSize();104105// Early exit if there is no need to allocate on the stack106if (StackSize == 0 && !MFI.adjustsStack())107return;108109const auto &CSI = MFI.getCalleeSavedInfo();110111unsigned spillAreaSize = CFI->getCalleeSaveAreaSize();112113uint64_t ActualSize = spillAreaSize + CFI->getVarArgsSaveSize();114115// First part stack allocation.116adjustReg(MBB, MBBI, DL, SPReg, SPReg, -(static_cast<int64_t>(ActualSize)),117MachineInstr::NoFlags);118119// Emit ".cfi_def_cfa_offset FirstSPAdjustAmount"120unsigned CFIIndex =121MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, ActualSize));122BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))123.addCFIIndex(CFIIndex);124125// The frame pointer is callee-saved, and code has been generated for us to126// save it to the stack. We need to skip over the storing of callee-saved127// registers as the frame pointer must be modified after it has been saved128// to the stack, not before.129// FIXME: assumes exactly one instruction is used to save each callee-saved130// register.131std::advance(MBBI, CSI.size());132133// Iterate over list of callee-saved registers and emit .cfi_offset134// directives.135for (const auto &Entry : CSI) {136int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx());137Register Reg = Entry.getReg();138139unsigned Num = TRI->getRegSizeInBits(Reg, MRI) / 32;140for (unsigned i = 0; i < Num; i++) {141unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(142nullptr, RI->getDwarfRegNum(Reg, true) + i, Offset + i * 4));143BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))144.addCFIIndex(CFIIndex);145}146}147148// Generate new FP.149if (hasFP(MF)) {150BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), FPReg)151.addReg(SPReg)152.setMIFlag(MachineInstr::FrameSetup);153154// Emit ".cfi_def_cfa_register $fp"155unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(156nullptr, RI->getDwarfRegNum(FPReg, true)));157BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))158.addCFIIndex(CFIIndex);159160// Second part stack allocation.161adjustReg(MBB, MBBI, DL, SPReg, SPReg,162-(static_cast<int64_t>(StackSize - ActualSize)),163MachineInstr::NoFlags);164165// Realign Stack166const CSKYRegisterInfo *RI = STI.getRegisterInfo();167if (RI->hasStackRealignment(MF)) {168Align MaxAlignment = MFI.getMaxAlign();169170const CSKYInstrInfo *TII = STI.getInstrInfo();171if (STI.hasE2() && isUInt<12>(~(-(int)MaxAlignment.value()))) {172BuildMI(MBB, MBBI, DL, TII->get(CSKY::ANDNI32), SPReg)173.addReg(SPReg)174.addImm(~(-(int)MaxAlignment.value()));175} else {176unsigned ShiftAmount = Log2(MaxAlignment);177178if (STI.hasE2()) {179Register VR =180MF.getRegInfo().createVirtualRegister(&CSKY::GPRRegClass);181BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSRI32), VR)182.addReg(SPReg)183.addImm(ShiftAmount);184BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSLI32), SPReg)185.addReg(VR)186.addImm(ShiftAmount);187} else {188Register VR =189MF.getRegInfo().createVirtualRegister(&CSKY::mGPRRegClass);190BuildMI(MBB, MBBI, DL, TII->get(CSKY::MOV16), VR).addReg(SPReg);191BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSRI16), VR)192.addReg(VR)193.addImm(ShiftAmount);194BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSLI16), VR)195.addReg(VR)196.addImm(ShiftAmount);197BuildMI(MBB, MBBI, DL, TII->get(CSKY::MOV16), SPReg).addReg(VR);198}199}200}201202// FP will be used to restore the frame in the epilogue, so we need203// another base register BP to record SP after re-alignment. SP will204// track the current stack after allocating variable sized objects.205if (hasBP(MF)) {206// move BP, SP207BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), BPReg).addReg(SPReg);208}209210} else {211adjustReg(MBB, MBBI, DL, SPReg, SPReg,212-(static_cast<int64_t>(StackSize - ActualSize)),213MachineInstr::NoFlags);214// Emit ".cfi_def_cfa_offset StackSize"215unsigned CFIIndex = MF.addFrameInst(216MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize()));217BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))218.addCFIIndex(CFIIndex);219}220}221222void CSKYFrameLowering::emitEpilogue(MachineFunction &MF,223MachineBasicBlock &MBB) const {224CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();225226MachineFrameInfo &MFI = MF.getFrameInfo();227Register FPReg = getFPReg(STI);228Register SPReg = CSKY::R14;229230// Get the insert location for the epilogue. If there were no terminators in231// the block, get the last instruction.232MachineBasicBlock::iterator MBBI = MBB.end();233DebugLoc DL;234if (!MBB.empty()) {235MBBI = MBB.getFirstTerminator();236if (MBBI == MBB.end())237MBBI = MBB.getLastNonDebugInstr();238DL = MBBI->getDebugLoc();239240// If this is not a terminator, the actual insert location should be after241// the last instruction.242if (!MBBI->isTerminator())243MBBI = std::next(MBBI);244}245246const auto &CSI = MFI.getCalleeSavedInfo();247uint64_t StackSize = MFI.getStackSize();248249uint64_t ActualSize =250CFI->getCalleeSaveAreaSize() + CFI->getVarArgsSaveSize();251252// Skip to before the restores of callee-saved registers253// FIXME: assumes exactly one instruction is used to restore each254// callee-saved register.255auto LastFrameDestroy = MBBI;256if (!CSI.empty())257LastFrameDestroy = std::prev(MBBI, CSI.size());258259if (hasFP(MF)) {260const CSKYInstrInfo *TII = STI.getInstrInfo();261BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::COPY), SPReg)262.addReg(FPReg)263.setMIFlag(MachineInstr::NoFlags);264} else {265adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, (StackSize - ActualSize),266MachineInstr::FrameDestroy);267}268269adjustReg(MBB, MBBI, DL, SPReg, SPReg, ActualSize,270MachineInstr::FrameDestroy);271}272273static unsigned EstimateFunctionSizeInBytes(const MachineFunction &MF,274const CSKYInstrInfo &TII) {275unsigned FnSize = 0;276for (auto &MBB : MF) {277for (auto &MI : MBB)278FnSize += TII.getInstSizeInBytes(MI);279}280FnSize += MF.getConstantPool()->getConstants().size() * 4;281return FnSize;282}283284static unsigned estimateRSStackSizeLimit(MachineFunction &MF,285const CSKYSubtarget &STI) {286unsigned Limit = (1 << 12) - 1;287288for (auto &MBB : MF) {289for (auto &MI : MBB) {290if (MI.isDebugInstr())291continue;292293for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {294if (!MI.getOperand(i).isFI())295continue;296297if (MI.getOpcode() == CSKY::SPILL_CARRY ||298MI.getOpcode() == CSKY::RESTORE_CARRY ||299MI.getOpcode() == CSKY::STORE_PAIR ||300MI.getOpcode() == CSKY::LOAD_PAIR) {301Limit = std::min(Limit, ((1U << 12) - 1) * 4);302break;303}304305if (MI.getOpcode() == CSKY::ADDI32) {306Limit = std::min(Limit, (1U << 12));307break;308}309310if (MI.getOpcode() == CSKY::ADDI16XZ) {311Limit = std::min(Limit, (1U << 3));312break;313}314315// ADDI16 will not require an extra register,316// it can reuse the destination.317if (MI.getOpcode() == CSKY::ADDI16)318break;319320// Otherwise check the addressing mode.321switch (MI.getDesc().TSFlags & CSKYII::AddrModeMask) {322default:323LLVM_DEBUG(MI.dump());324llvm_unreachable(325"Unhandled addressing mode in stack size limit calculation");326case CSKYII::AddrMode32B:327Limit = std::min(Limit, (1U << 12) - 1);328break;329case CSKYII::AddrMode32H:330Limit = std::min(Limit, ((1U << 12) - 1) * 2);331break;332case CSKYII::AddrMode32WD:333Limit = std::min(Limit, ((1U << 12) - 1) * 4);334break;335case CSKYII::AddrMode16B:336Limit = std::min(Limit, (1U << 5) - 1);337break;338case CSKYII::AddrMode16H:339Limit = std::min(Limit, ((1U << 5) - 1) * 2);340break;341case CSKYII::AddrMode16W:342Limit = std::min(Limit, ((1U << 5) - 1) * 4);343break;344case CSKYII::AddrMode32SDF:345Limit = std::min(Limit, ((1U << 8) - 1) * 4);346break;347}348break; // At most one FI per instruction349}350}351}352353return Limit;354}355356void CSKYFrameLowering::determineCalleeSaves(MachineFunction &MF,357BitVector &SavedRegs,358RegScavenger *RS) const {359TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);360361CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();362const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();363const CSKYInstrInfo *TII = STI.getInstrInfo();364const MachineRegisterInfo &MRI = MF.getRegInfo();365MachineFrameInfo &MFI = MF.getFrameInfo();366367if (hasFP(MF))368SavedRegs.set(CSKY::R8);369370// Mark BP as used if function has dedicated base pointer.371if (hasBP(MF))372SavedRegs.set(CSKY::R7);373374// If interrupt is enabled and there are calls in the handler,375// unconditionally save all Caller-saved registers and376// all FP registers, regardless whether they are used.377if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) {378379static const MCPhysReg CSRegs[] = {CSKY::R0, CSKY::R1, CSKY::R2, CSKY::R3,380CSKY::R12, CSKY::R13, 0};381382for (unsigned i = 0; CSRegs[i]; ++i)383SavedRegs.set(CSRegs[i]);384385if (STI.hasHighRegisters()) {386387static const MCPhysReg CSHRegs[] = {CSKY::R18, CSKY::R19, CSKY::R20,388CSKY::R21, CSKY::R22, CSKY::R23,389CSKY::R24, CSKY::R25, 0};390391for (unsigned i = 0; CSHRegs[i]; ++i)392SavedRegs.set(CSHRegs[i]);393}394395static const MCPhysReg CSF32Regs[] = {396CSKY::F8_32, CSKY::F9_32, CSKY::F10_32,397CSKY::F11_32, CSKY::F12_32, CSKY::F13_32,398CSKY::F14_32, CSKY::F15_32, 0};399static const MCPhysReg CSF64Regs[] = {400CSKY::F8_64, CSKY::F9_64, CSKY::F10_64,401CSKY::F11_64, CSKY::F12_64, CSKY::F13_64,402CSKY::F14_64, CSKY::F15_64, 0};403404const MCPhysReg *FRegs = NULL;405if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())406FRegs = CSF64Regs;407else if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())408FRegs = CSF32Regs;409410if (FRegs != NULL) {411const MCPhysReg *Regs = MF.getRegInfo().getCalleeSavedRegs();412413for (unsigned i = 0; Regs[i]; ++i)414if (CSKY::FPR32RegClass.contains(Regs[i]) ||415CSKY::FPR64RegClass.contains(Regs[i])) {416unsigned x = 0;417for (; FRegs[x]; ++x)418if (FRegs[x] == Regs[i])419break;420if (FRegs[x] == 0)421SavedRegs.set(Regs[i]);422}423}424}425426unsigned CSStackSize = 0;427for (unsigned Reg : SavedRegs.set_bits()) {428auto RegSize = TRI->getRegSizeInBits(Reg, MRI) / 8;429CSStackSize += RegSize;430}431432CFI->setCalleeSaveAreaSize(CSStackSize);433434uint64_t Limit = estimateRSStackSizeLimit(MF, STI);435436bool BigFrame = (MFI.estimateStackSize(MF) + CSStackSize >= Limit);437438if (BigFrame || CFI->isCRSpilled() || !STI.hasE2()) {439const TargetRegisterClass *RC = &CSKY::GPRRegClass;440unsigned size = TRI->getSpillSize(*RC);441Align align = TRI->getSpillAlign(*RC);442443RS->addScavengingFrameIndex(MFI.CreateStackObject(size, align, false));444}445446unsigned FnSize = EstimateFunctionSizeInBytes(MF, *TII);447// Force R15 to be spilled if the function size is > 65534. This enables448// use of BSR to implement far jump.449if (FnSize >= ((1 << (16 - 1)) * 2))450SavedRegs.set(CSKY::R15);451452CFI->setLRIsSpilled(SavedRegs.test(CSKY::R15));453}454455// Not preserve stack space within prologue for outgoing variables when the456// function contains variable size objects and let eliminateCallFramePseudoInstr457// preserve stack space for it.458bool CSKYFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {459return !MF.getFrameInfo().hasVarSizedObjects();460}461462bool CSKYFrameLowering::spillCalleeSavedRegisters(463MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,464ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {465if (CSI.empty())466return true;467468MachineFunction *MF = MBB.getParent();469const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();470DebugLoc DL;471if (MI != MBB.end() && !MI->isDebugInstr())472DL = MI->getDebugLoc();473474for (auto &CS : CSI) {475// Insert the spill to the stack frame.476Register Reg = CS.getReg();477const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);478TII.storeRegToStackSlot(MBB, MI, Reg, true, CS.getFrameIdx(), RC, TRI,479Register());480}481482return true;483}484485bool CSKYFrameLowering::restoreCalleeSavedRegisters(486MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,487MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {488if (CSI.empty())489return true;490491MachineFunction *MF = MBB.getParent();492const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();493DebugLoc DL;494if (MI != MBB.end() && !MI->isDebugInstr())495DL = MI->getDebugLoc();496497for (auto &CS : reverse(CSI)) {498Register Reg = CS.getReg();499const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);500TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI,501Register());502assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!");503}504505return true;506}507508// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions.509MachineBasicBlock::iterator CSKYFrameLowering::eliminateCallFramePseudoInstr(510MachineFunction &MF, MachineBasicBlock &MBB,511MachineBasicBlock::iterator MI) const {512Register SPReg = CSKY::R14;513DebugLoc DL = MI->getDebugLoc();514515if (!hasReservedCallFrame(MF)) {516// If space has not been reserved for a call frame, ADJCALLSTACKDOWN and517// ADJCALLSTACKUP must be converted to instructions manipulating the stack518// pointer. This is necessary when there is a variable length stack519// allocation (e.g. alloca), which means it's not possible to allocate520// space for outgoing arguments from within the function prologue.521int64_t Amount = MI->getOperand(0).getImm();522523if (Amount != 0) {524// Ensure the stack remains aligned after adjustment.525Amount = alignSPAdjust(Amount);526527if (MI->getOpcode() == CSKY::ADJCALLSTACKDOWN)528Amount = -Amount;529530adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags);531}532}533534return MBB.erase(MI);535}536537void CSKYFrameLowering::adjustReg(MachineBasicBlock &MBB,538MachineBasicBlock::iterator MBBI,539const DebugLoc &DL, Register DestReg,540Register SrcReg, int64_t Val,541MachineInstr::MIFlag Flag) const {542const CSKYInstrInfo *TII = STI.getInstrInfo();543544if (DestReg == SrcReg && Val == 0)545return;546547// TODO: Add 16-bit instruction support with immediate num548if (STI.hasE2() && isUInt<12>(std::abs(Val) - 1)) {549BuildMI(MBB, MBBI, DL, TII->get(Val < 0 ? CSKY::SUBI32 : CSKY::ADDI32),550DestReg)551.addReg(SrcReg)552.addImm(std::abs(Val))553.setMIFlag(Flag);554} else if (!STI.hasE2() && isShiftedUInt<7, 2>(std::abs(Val))) {555BuildMI(MBB, MBBI, DL,556TII->get(Val < 0 ? CSKY::SUBI16SPSP : CSKY::ADDI16SPSP), CSKY::R14)557.addReg(CSKY::R14, RegState::Kill)558.addImm(std::abs(Val))559.setMIFlag(Flag);560} else {561562unsigned Op = 0;563564if (STI.hasE2()) {565Op = Val < 0 ? CSKY::SUBU32 : CSKY::ADDU32;566} else {567assert(SrcReg == DestReg);568Op = Val < 0 ? CSKY::SUBU16XZ : CSKY::ADDU16XZ;569}570571Register ScratchReg = TII->movImm(MBB, MBBI, DL, std::abs(Val), Flag);572573BuildMI(MBB, MBBI, DL, TII->get(Op), DestReg)574.addReg(SrcReg)575.addReg(ScratchReg, RegState::Kill)576.setMIFlag(Flag);577}578}579580StackOffset581CSKYFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,582Register &FrameReg) const {583const CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();584const MachineFrameInfo &MFI = MF.getFrameInfo();585const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();586const auto &CSI = MFI.getCalleeSavedInfo();587588int MinCSFI = 0;589int MaxCSFI = -1;590591int Offset = MFI.getObjectOffset(FI) + MFI.getOffsetAdjustment();592593if (CSI.size()) {594MinCSFI = CSI[0].getFrameIdx();595MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();596}597598if (FI >= MinCSFI && FI <= MaxCSFI) {599FrameReg = CSKY::R14;600Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();601} else if (RI->hasStackRealignment(MF)) {602assert(hasFP(MF));603if (!MFI.isFixedObjectIndex(FI)) {604FrameReg = hasBP(MF) ? getBPReg(STI) : CSKY::R14;605Offset += MFI.getStackSize();606} else {607FrameReg = getFPReg(STI);608Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();609}610} else {611if (MFI.isFixedObjectIndex(FI) && hasFP(MF)) {612FrameReg = getFPReg(STI);613Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();614} else {615FrameReg = hasBP(MF) ? getBPReg(STI) : CSKY::R14;616Offset += MFI.getStackSize();617}618}619620return StackOffset::getFixed(Offset);621}622623624