//===-- CSKYFrameLowering.cpp - CSKY Frame Information ------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the CSKY implementation of TargetFrameLowering class.
//
//===----------------------------------------------------------------------===//

#include "CSKYFrameLowering.h"
#include "CSKYMachineFunctionInfo.h"
#include "CSKYSubtarget.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/MC/MCDwarf.h"

using namespace llvm;

#define DEBUG_TYPE "csky-frame-lowering"

// Returns the register used to hold the frame pointer.
static Register getFPReg(const CSKYSubtarget &STI) { return CSKY::R8; }

// To avoid the BP value clobbered by a function call, we need to choose a
// callee saved register to save the value.
static Register getBPReg(const CSKYSubtarget &STI) { return CSKY::R7; }

bool CSKYFrameLowering::hasFPImpl(const MachineFunction &MF) const {
  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();

  const MachineFrameInfo &MFI = MF.getFrameInfo();
  return MF.getTarget().Options.DisableFramePointerElim(MF) ||
         RegInfo->hasStackRealignment(MF) || MFI.hasVarSizedObjects() ||
         MFI.isFrameAddressTaken();
}

bool CSKYFrameLowering::hasBP(const MachineFunction &MF) const {
  const MachineFrameInfo &MFI = MF.getFrameInfo();

  return MFI.hasVarSizedObjects();
}

// Determines the size of the frame and maximum call frame size.
void CSKYFrameLowering::determineFrameLayout(MachineFunction &MF) const {
  MachineFrameInfo &MFI = MF.getFrameInfo();
  const CSKYRegisterInfo *RI = STI.getRegisterInfo();

  // Get the number of bytes to allocate from the FrameInfo.
  uint64_t FrameSize = MFI.getStackSize();

  // Get the alignment.
  Align StackAlign = getStackAlign();
  if (RI->hasStackRealignment(MF)) {
    Align MaxStackAlign = std::max(StackAlign, MFI.getMaxAlign());
    FrameSize += (MaxStackAlign.value() - StackAlign.value());
    StackAlign = MaxStackAlign;
  }

  // Set Max Call Frame Size
  uint64_t MaxCallSize = alignTo(MFI.getMaxCallFrameSize(), StackAlign);
  MFI.setMaxCallFrameSize(MaxCallSize);

  // Make sure the frame is aligned.
  FrameSize = alignTo(FrameSize, StackAlign);

  // Update frame info.
  MFI.setStackSize(FrameSize);
}

void CSKYFrameLowering::emitPrologue(MachineFunction &MF,
                                     MachineBasicBlock &MBB) const {
  CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  const CSKYRegisterInfo *RI = STI.getRegisterInfo();
  const CSKYInstrInfo *TII = STI.getInstrInfo();
  MachineBasicBlock::iterator MBBI = MBB.begin();
  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
  const MachineRegisterInfo &MRI = MF.getRegInfo();

  Register FPReg = getFPReg(STI);
  Register SPReg = CSKY::R14;
  Register BPReg = getBPReg(STI);

  // Debug location must be unknown since the first debug location is used
  // to determine the end of the prologue.
  DebugLoc DL;

  if (MF.getFunction().hasFnAttribute("interrupt"))
    BuildMI(MBB, MBBI, DL, TII->get(CSKY::NIE));

  // Determine the correct frame layout
  determineFrameLayout(MF);

  // FIXME (note copied from Lanai): This appears to be overallocating.  Needs
  // investigation. Get the number of bytes to allocate from the FrameInfo.
  uint64_t StackSize = MFI.getStackSize();

  // Early exit if there is no need to allocate on the stack
  if (StackSize == 0 && !MFI.adjustsStack())
    return;

  const auto &CSI = MFI.getCalleeSavedInfo();

  unsigned spillAreaSize = CFI->getCalleeSaveAreaSize();

  uint64_t ActualSize = spillAreaSize + CFI->getVarArgsSaveSize();

  // First part stack allocation.
  adjustReg(MBB, MBBI, DL, SPReg, SPReg, -(static_cast<int64_t>(ActualSize)),
            MachineInstr::NoFlags);

  // Emit ".cfi_def_cfa_offset FirstSPAdjustAmount"
  unsigned CFIIndex =
      MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, ActualSize));
  BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
      .addCFIIndex(CFIIndex);

  // The frame pointer is callee-saved, and code has been generated for us to
  // save it to the stack. We need to skip over the storing of callee-saved
  // registers as the frame pointer must be modified after it has been saved
  // to the stack, not before.
  // FIXME: assumes exactly one instruction is used to save each callee-saved
  // register.
  std::advance(MBBI, CSI.size());

  // Iterate over list of callee-saved registers and emit .cfi_offset
  // directives.
  for (const auto &Entry : CSI) {
    int64_t Offset = MFI.getObjectOffset(Entry.getFrameIdx());
    MCRegister Reg = Entry.getReg();

    unsigned Num = TRI->getRegSizeInBits(Reg, MRI) / 32;
    for (unsigned i = 0; i < Num; i++) {
      unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
          nullptr, RI->getDwarfRegNum(Reg, true) + i, Offset + i * 4));
      BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
          .addCFIIndex(CFIIndex);
    }
  }

  // Generate new FP.
  if (hasFP(MF)) {
    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), FPReg)
        .addReg(SPReg)
        .setMIFlag(MachineInstr::FrameSetup);

    // Emit ".cfi_def_cfa_register $fp"
    unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(
        nullptr, RI->getDwarfRegNum(FPReg, true)));
    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex);

    // Second part stack allocation.
    adjustReg(MBB, MBBI, DL, SPReg, SPReg,
              -(static_cast<int64_t>(StackSize - ActualSize)),
              MachineInstr::NoFlags);

    // Realign Stack
    const CSKYRegisterInfo *RI = STI.getRegisterInfo();
    if (RI->hasStackRealignment(MF)) {
      Align MaxAlignment = MFI.getMaxAlign();

      const CSKYInstrInfo *TII = STI.getInstrInfo();
      if (STI.hasE2() && isUInt<12>(~(-(int)MaxAlignment.value()))) {
        BuildMI(MBB, MBBI, DL, TII->get(CSKY::ANDNI32), SPReg)
            .addReg(SPReg)
            .addImm(~(-(int)MaxAlignment.value()));
      } else {
        unsigned ShiftAmount = Log2(MaxAlignment);

        if (STI.hasE2()) {
          Register VR =
              MF.getRegInfo().createVirtualRegister(&CSKY::GPRRegClass);
          BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSRI32), VR)
              .addReg(SPReg)
              .addImm(ShiftAmount);
          BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSLI32), SPReg)
              .addReg(VR)
              .addImm(ShiftAmount);
        } else {
          Register VR =
              MF.getRegInfo().createVirtualRegister(&CSKY::mGPRRegClass);
          BuildMI(MBB, MBBI, DL, TII->get(CSKY::MOV16), VR).addReg(SPReg);
          BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSRI16), VR)
              .addReg(VR)
              .addImm(ShiftAmount);
          BuildMI(MBB, MBBI, DL, TII->get(CSKY::LSLI16), VR)
              .addReg(VR)
              .addImm(ShiftAmount);
          BuildMI(MBB, MBBI, DL, TII->get(CSKY::MOV16), SPReg).addReg(VR);
        }
      }
    }

    // FP will be used to restore the frame in the epilogue, so we need
    // another base register BP to record SP after re-alignment. SP will
    // track the current stack after allocating variable sized objects.
    if (hasBP(MF)) {
      // move BP, SP
      BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::COPY), BPReg).addReg(SPReg);
    }

  } else {
    adjustReg(MBB, MBBI, DL, SPReg, SPReg,
              -(static_cast<int64_t>(StackSize - ActualSize)),
              MachineInstr::NoFlags);
    // Emit ".cfi_def_cfa_offset StackSize"
    unsigned CFIIndex = MF.addFrameInst(
        MCCFIInstruction::cfiDefCfaOffset(nullptr, MFI.getStackSize()));
    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex);
  }
}

void CSKYFrameLowering::emitEpilogue(MachineFunction &MF,
                                     MachineBasicBlock &MBB) const {
  CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();

  MachineFrameInfo &MFI = MF.getFrameInfo();
  Register FPReg = getFPReg(STI);
  Register SPReg = CSKY::R14;

  // Get the insert location for the epilogue. If there were no terminators in
  // the block, get the last instruction.
  MachineBasicBlock::iterator MBBI = MBB.end();
  DebugLoc DL;
  if (!MBB.empty()) {
    MBBI = MBB.getFirstTerminator();
    if (MBBI == MBB.end())
      MBBI = MBB.getLastNonDebugInstr();
    DL = MBBI->getDebugLoc();

    // If this is not a terminator, the actual insert location should be after
    // the last instruction.
    if (!MBBI->isTerminator())
      MBBI = std::next(MBBI);
  }

  const auto &CSI = MFI.getCalleeSavedInfo();
  uint64_t StackSize = MFI.getStackSize();

  uint64_t ActualSize =
      CFI->getCalleeSaveAreaSize() + CFI->getVarArgsSaveSize();

  // Skip to before the restores of callee-saved registers
  // FIXME: assumes exactly one instruction is used to restore each
  // callee-saved register.
  auto LastFrameDestroy = MBBI;
  if (!CSI.empty())
    LastFrameDestroy = std::prev(MBBI, CSI.size());

  if (hasFP(MF)) {
    const CSKYInstrInfo *TII = STI.getInstrInfo();
    BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::COPY), SPReg)
        .addReg(FPReg)
        .setMIFlag(MachineInstr::NoFlags);
  } else {
    adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, (StackSize - ActualSize),
              MachineInstr::FrameDestroy);
  }

  adjustReg(MBB, MBBI, DL, SPReg, SPReg, ActualSize,
            MachineInstr::FrameDestroy);
}

static unsigned EstimateFunctionSizeInBytes(const MachineFunction &MF,
                                            const CSKYInstrInfo &TII) {
  unsigned FnSize = 0;
  for (auto &MBB : MF) {
    for (auto &MI : MBB)
      FnSize += TII.getInstSizeInBytes(MI);
  }
  FnSize += MF.getConstantPool()->getConstants().size() * 4;
  return FnSize;
}

static unsigned estimateRSStackSizeLimit(MachineFunction &MF,
                                         const CSKYSubtarget &STI) {
  unsigned Limit = (1 << 12) - 1;

  for (auto &MBB : MF) {
    for (auto &MI : MBB) {
      if (MI.isDebugInstr())
        continue;

      for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
        if (!MI.getOperand(i).isFI())
          continue;

        if (MI.getOpcode() == CSKY::SPILL_CARRY ||
            MI.getOpcode() == CSKY::RESTORE_CARRY ||
            MI.getOpcode() == CSKY::STORE_PAIR ||
            MI.getOpcode() == CSKY::LOAD_PAIR) {
          Limit = std::min(Limit, ((1U << 12) - 1) * 4);
          break;
        }

        if (MI.getOpcode() == CSKY::ADDI32) {
          Limit = std::min(Limit, (1U << 12));
          break;
        }

        if (MI.getOpcode() == CSKY::ADDI16XZ) {
          Limit = std::min(Limit, (1U << 3));
          break;
        }

        // ADDI16 will not require an extra register,
        // it can reuse the destination.
        if (MI.getOpcode() == CSKY::ADDI16)
          break;

        // Otherwise check the addressing mode.
        switch (MI.getDesc().TSFlags & CSKYII::AddrModeMask) {
        default:
          LLVM_DEBUG(MI.dump());
          llvm_unreachable(
              "Unhandled addressing mode in stack size limit calculation");
        case CSKYII::AddrMode32B:
          Limit = std::min(Limit, (1U << 12) - 1);
          break;
        case CSKYII::AddrMode32H:
          Limit = std::min(Limit, ((1U << 12) - 1) * 2);
          break;
        case CSKYII::AddrMode32WD:
          Limit = std::min(Limit, ((1U << 12) - 1) * 4);
          break;
        case CSKYII::AddrMode16B:
          Limit = std::min(Limit, (1U << 5) - 1);
          break;
        case CSKYII::AddrMode16H:
          Limit = std::min(Limit, ((1U << 5) - 1) * 2);
          break;
        case CSKYII::AddrMode16W:
          Limit = std::min(Limit, ((1U << 5) - 1) * 4);
          break;
        case CSKYII::AddrMode32SDF:
          Limit = std::min(Limit, ((1U << 8) - 1) * 4);
          break;
        }
        break; // At most one FI per instruction
      }
    }
  }

  return Limit;
}

void CSKYFrameLowering::determineCalleeSaves(MachineFunction &MF,
                                             BitVector &SavedRegs,
                                             RegScavenger *RS) const {
  TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);

  CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
  const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
  const CSKYInstrInfo *TII = STI.getInstrInfo();
  const MachineRegisterInfo &MRI = MF.getRegInfo();
  MachineFrameInfo &MFI = MF.getFrameInfo();

  if (hasFP(MF))
    SavedRegs.set(CSKY::R8);

  // Mark BP as used if function has dedicated base pointer.
  if (hasBP(MF))
    SavedRegs.set(CSKY::R7);

  // If interrupt is enabled and there are calls in the handler,
  // unconditionally save all Caller-saved registers and
  // all FP registers, regardless whether they are used.
  if (MF.getFunction().hasFnAttribute("interrupt") && MFI.hasCalls()) {

    static const MCPhysReg CSRegs[] = {CSKY::R0,  CSKY::R1,  CSKY::R2, CSKY::R3,
                                       CSKY::R12, CSKY::R13, 0};

    for (unsigned i = 0; CSRegs[i]; ++i)
      SavedRegs.set(CSRegs[i]);

    if (STI.hasHighRegisters()) {

      static const MCPhysReg CSHRegs[] = {CSKY::R18, CSKY::R19, CSKY::R20,
                                          CSKY::R21, CSKY::R22, CSKY::R23,
                                          CSKY::R24, CSKY::R25, 0};

      for (unsigned i = 0; CSHRegs[i]; ++i)
        SavedRegs.set(CSHRegs[i]);
    }

    static const MCPhysReg CSF32Regs[] = {
        CSKY::F8_32,  CSKY::F9_32,  CSKY::F10_32,
        CSKY::F11_32, CSKY::F12_32, CSKY::F13_32,
        CSKY::F14_32, CSKY::F15_32, 0};
    static const MCPhysReg CSF64Regs[] = {
        CSKY::F8_64,  CSKY::F9_64,  CSKY::F10_64,
        CSKY::F11_64, CSKY::F12_64, CSKY::F13_64,
        CSKY::F14_64, CSKY::F15_64, 0};

    const MCPhysReg *FRegs = NULL;
    if (STI.hasFPUv2DoubleFloat() || STI.hasFPUv3DoubleFloat())
      FRegs = CSF64Regs;
    else if (STI.hasFPUv2SingleFloat() || STI.hasFPUv3SingleFloat())
      FRegs = CSF32Regs;

    if (FRegs != NULL) {
      const MCPhysReg *Regs = MF.getRegInfo().getCalleeSavedRegs();

      for (unsigned i = 0; Regs[i]; ++i)
        if (CSKY::FPR32RegClass.contains(Regs[i]) ||
            CSKY::FPR64RegClass.contains(Regs[i])) {
          unsigned x = 0;
          for (; FRegs[x]; ++x)
            if (FRegs[x] == Regs[i])
              break;
          if (FRegs[x] == 0)
            SavedRegs.set(Regs[i]);
        }
    }
  }

  unsigned CSStackSize = 0;
  for (unsigned Reg : SavedRegs.set_bits()) {
    auto RegSize = TRI->getRegSizeInBits(Reg, MRI) / 8;
    CSStackSize += RegSize;
  }

  CFI->setCalleeSaveAreaSize(CSStackSize);

  uint64_t Limit = estimateRSStackSizeLimit(MF, STI);

  bool BigFrame = (MFI.estimateStackSize(MF) + CSStackSize >= Limit);

  if (BigFrame || CFI->isCRSpilled() || !STI.hasE2()) {
    const TargetRegisterClass *RC = &CSKY::GPRRegClass;
    unsigned size = TRI->getSpillSize(*RC);
    Align align = TRI->getSpillAlign(*RC);

    RS->addScavengingFrameIndex(MFI.CreateSpillStackObject(size, align));
  }

  unsigned FnSize = EstimateFunctionSizeInBytes(MF, *TII);
  // Force R15 to be spilled if the function size is > 65534. This enables
  // use of BSR to implement far jump.
  if (FnSize >= ((1 << (16 - 1)) * 2))
    SavedRegs.set(CSKY::R15);

  CFI->setLRIsSpilled(SavedRegs.test(CSKY::R15));
}

// Not preserve stack space within prologue for outgoing variables when the
// function contains variable size objects and let eliminateCallFramePseudoInstr
// preserve stack space for it.
bool CSKYFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
  return !MF.getFrameInfo().hasVarSizedObjects();
}

bool CSKYFrameLowering::spillCalleeSavedRegisters(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
    ArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
  if (CSI.empty())
    return true;

  MachineFunction *MF = MBB.getParent();
  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
  DebugLoc DL;
  if (MI != MBB.end() && !MI->isDebugInstr())
    DL = MI->getDebugLoc();

  for (auto &CS : CSI) {
    // Insert the spill to the stack frame.
    MCRegister Reg = CS.getReg();
    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
    TII.storeRegToStackSlot(MBB, MI, Reg, true, CS.getFrameIdx(), RC, TRI,
                            Register());
  }

  return true;
}

bool CSKYFrameLowering::restoreCalleeSavedRegisters(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
    MutableArrayRef<CalleeSavedInfo> CSI, const TargetRegisterInfo *TRI) const {
  if (CSI.empty())
    return true;

  MachineFunction *MF = MBB.getParent();
  const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
  DebugLoc DL;
  if (MI != MBB.end() && !MI->isDebugInstr())
    DL = MI->getDebugLoc();

  for (auto &CS : reverse(CSI)) {
    MCRegister Reg = CS.getReg();
    const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
    TII.loadRegFromStackSlot(MBB, MI, Reg, CS.getFrameIdx(), RC, TRI,
                             Register());
    assert(MI != MBB.begin() && "loadRegFromStackSlot didn't insert any code!");
  }

  return true;
}

// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions.
MachineBasicBlock::iterator CSKYFrameLowering::eliminateCallFramePseudoInstr(
    MachineFunction &MF, MachineBasicBlock &MBB,
    MachineBasicBlock::iterator MI) const {
  Register SPReg = CSKY::R14;
  DebugLoc DL = MI->getDebugLoc();

  if (!hasReservedCallFrame(MF)) {
    // If space has not been reserved for a call frame, ADJCALLSTACKDOWN and
    // ADJCALLSTACKUP must be converted to instructions manipulating the stack
    // pointer. This is necessary when there is a variable length stack
    // allocation (e.g. alloca), which means it's not possible to allocate
    // space for outgoing arguments from within the function prologue.
    int64_t Amount = MI->getOperand(0).getImm();

    if (Amount != 0) {
      // Ensure the stack remains aligned after adjustment.
      Amount = alignSPAdjust(Amount);

      if (MI->getOpcode() == CSKY::ADJCALLSTACKDOWN)
        Amount = -Amount;

      adjustReg(MBB, MI, DL, SPReg, SPReg, Amount, MachineInstr::NoFlags);
    }
  }

  return MBB.erase(MI);
}

void CSKYFrameLowering::adjustReg(MachineBasicBlock &MBB,
                                  MachineBasicBlock::iterator MBBI,
                                  const DebugLoc &DL, Register DestReg,
                                  Register SrcReg, int64_t Val,
                                  MachineInstr::MIFlag Flag) const {
  const CSKYInstrInfo *TII = STI.getInstrInfo();

  if (DestReg == SrcReg && Val == 0)
    return;

  // TODO: Add 16-bit instruction support with immediate num
  if (STI.hasE2() && isUInt<12>(std::abs(Val) - 1)) {
    BuildMI(MBB, MBBI, DL, TII->get(Val < 0 ? CSKY::SUBI32 : CSKY::ADDI32),
            DestReg)
        .addReg(SrcReg)
        .addImm(std::abs(Val))
        .setMIFlag(Flag);
  } else if (!STI.hasE2() && isShiftedUInt<7, 2>(std::abs(Val))) {
    BuildMI(MBB, MBBI, DL,
            TII->get(Val < 0 ? CSKY::SUBI16SPSP : CSKY::ADDI16SPSP), CSKY::R14)
        .addReg(CSKY::R14, RegState::Kill)
        .addImm(std::abs(Val))
        .setMIFlag(Flag);
  } else {

    unsigned Op = 0;

    if (STI.hasE2()) {
      Op = Val < 0 ? CSKY::SUBU32 : CSKY::ADDU32;
    } else {
      assert(SrcReg == DestReg);
      Op = Val < 0 ? CSKY::SUBU16XZ : CSKY::ADDU16XZ;
    }

    Register ScratchReg = TII->movImm(MBB, MBBI, DL, std::abs(Val), Flag);

    BuildMI(MBB, MBBI, DL, TII->get(Op), DestReg)
        .addReg(SrcReg)
        .addReg(ScratchReg, RegState::Kill)
        .setMIFlag(Flag);
  }
}

StackOffset
CSKYFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
                                          Register &FrameReg) const {
  const CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
  const MachineFrameInfo &MFI = MF.getFrameInfo();
  const TargetRegisterInfo *RI = MF.getSubtarget().getRegisterInfo();
  const auto &CSI = MFI.getCalleeSavedInfo();

  int MinCSFI = 0;
  int MaxCSFI = -1;

  int Offset = MFI.getObjectOffset(FI) + MFI.getOffsetAdjustment();

  if (CSI.size()) {
    MinCSFI = CSI[0].getFrameIdx();
    MaxCSFI = CSI[CSI.size() - 1].getFrameIdx();
  }

  if (FI >= MinCSFI && FI <= MaxCSFI) {
    FrameReg = CSKY::R14;
    Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();
  } else if (RI->hasStackRealignment(MF)) {
    assert(hasFP(MF));
    if (!MFI.isFixedObjectIndex(FI)) {
      FrameReg = hasBP(MF) ? getBPReg(STI) : CSKY::R14;
      Offset += MFI.getStackSize();
    } else {
      FrameReg = getFPReg(STI);
      Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();
    }
  } else {
    if (MFI.isFixedObjectIndex(FI) && hasFP(MF)) {
      FrameReg = getFPReg(STI);
      Offset += CFI->getVarArgsSaveSize() + CFI->getCalleeSaveAreaSize();
    } else {
      FrameReg = hasBP(MF) ? getBPReg(STI) : CSKY::R14;
      Offset += MFI.getStackSize();
    }
  }

  return StackOffset::getFixed(Offset);
}
