//===- ARCFrameLowering.cpp - ARC Frame Information -------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the ARC implementation of the TargetFrameLowering class.
//
//===----------------------------------------------------------------------===//

#include "ARCFrameLowering.h"
#include "ARCMachineFunctionInfo.h"
#include "ARCSubtarget.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetRegisterInfo.h"

#define DEBUG_TYPE "arc-frame-lowering"

using namespace llvm;

static cl::opt<bool>
    UseSaveRestoreFunclet("arc-save-restore-funclet", cl::Hidden,
                          cl::desc("Use arc callee save/restore functions"),
                          cl::init(true));

static const char *store_funclet_name[] = {
    "__st_r13_to_r15", "__st_r13_to_r16", "__st_r13_to_r17", "__st_r13_to_r18",
    "__st_r13_to_r19", "__st_r13_to_r20", "__st_r13_to_r21", "__st_r13_to_r22",
    "__st_r13_to_r23", "__st_r13_to_r24", "__st_r13_to_r25",
};

static const char *load_funclet_name[] = {
    "__ld_r13_to_r15", "__ld_r13_to_r16", "__ld_r13_to_r17", "__ld_r13_to_r18",
    "__ld_r13_to_r19", "__ld_r13_to_r20", "__ld_r13_to_r21", "__ld_r13_to_r22",
    "__ld_r13_to_r23", "__ld_r13_to_r24", "__ld_r13_to_r25",
};

static void generateStackAdjustment(MachineBasicBlock &MBB,
                                    MachineBasicBlock::iterator MBBI,
                                    const ARCInstrInfo &TII, DebugLoc dl,
                                    int Amount, int StackPtr) {
  unsigned AdjOp;
  if (!Amount)
    return;
  bool Positive;
  unsigned AbsAmount;
  if (Amount < 0) {
    AbsAmount = -Amount;
    Positive = false;
  } else {
    AbsAmount = Amount;
    Positive = true;
  }

  DEBUG(dbgs() << "Internal: adjust stack by: " << Amount << "," << AbsAmount
               << "\n");

  assert((AbsAmount % 4 == 0) && "Stack adjustments must be 4-byte aligned.");
  if (isUInt<6>(AbsAmount))
    AdjOp = Positive ? ARC::ADD_rru6 : ARC::SUB_rru6;
  else
    AdjOp = Positive ? ARC::ADD_rrlimm : ARC::SUB_rrlimm;

  BuildMI(MBB, MBBI, dl, TII.get(AdjOp), StackPtr)
      .addReg(StackPtr)
      .addImm(AbsAmount);
}

static unsigned
determineLastCalleeSave(const std::vector<CalleeSavedInfo> &CSI) {
  unsigned Last = 0;
  for (auto Reg : CSI) {
    assert(Reg.getReg() >= ARC::R13 && Reg.getReg() <= ARC::R25 &&
           "Unexpected callee saved reg.");
    if (Reg.getReg() > Last)
      Last = Reg.getReg();
  }
  return Last;
}

void ARCFrameLowering::determineCalleeSaves(MachineFunction &MF,
                                            BitVector &SavedRegs,
                                            RegScavenger *RS) const {
  DEBUG(dbgs() << "Determine Callee Saves: " << MF.getFunction()->getName()
               << "\n");
  TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
  SavedRegs.set(ARC::BLINK);
}

void ARCFrameLowering::adjustStackToMatchRecords(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
    bool Allocate) const {
  MachineFunction &MF = *MBB.getParent();
  int ScalarAlloc = MF.getFrameInfo().getStackSize();

  if (Allocate) {
    // Allocate by adjusting by the negative of what the record holder tracked
    // it tracked a positive offset in a downward growing stack.
    ScalarAlloc = -ScalarAlloc;
  }

  generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), DebugLoc(),
                          ScalarAlloc, ARC::SP);
}

/// Insert prolog code into the function.
/// For ARC, this inserts a call to a function that puts required callee saved
/// registers onto the stack, when enough callee saved registers are required.
void ARCFrameLowering::emitPrologue(MachineFunction &MF,
                                    MachineBasicBlock &MBB) const {
  DEBUG(dbgs() << "Emit Prologue: " << MF.getFunction()->getName() << "\n");
  auto *AFI = MF.getInfo<ARCFunctionInfo>();
  MachineModuleInfo &MMI = MF.getMMI();
  MCContext &Context = MMI.getContext();
  const MCRegisterInfo *MRI = Context.getRegisterInfo();
  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
  MachineBasicBlock::iterator MBBI = MBB.begin();
  // Debug location must be unknown since the first debug location is used
  // to determine the end of the prologue.
  DebugLoc dl;
  MachineFrameInfo &MFI = MF.getFrameInfo();
  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
  unsigned Last = determineLastCalleeSave(CSI);
  unsigned StackSlotsUsedByFunclet = 0;
  bool SavedBlink = false;
  unsigned AlreadyAdjusted = 0;
  if (MF.getFunction()->isVarArg()) {
    // Add in the varargs area here first.
    DEBUG(dbgs() << "Varargs\n");
    unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
    BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(VarArgsBytes);
  }
  if (hasFP(MF)) {
    DEBUG(dbgs() << "Saving FP\n");
    BuildMI(MBB, MBBI, dl, TII->get(ARC::ST_AW_rs9))
        .addReg(ARC::SP, RegState::Define)
        .addReg(ARC::FP)
        .addReg(ARC::SP)
        .addImm(-4);
    AlreadyAdjusted += 4;
  }
  if (UseSaveRestoreFunclet && Last > ARC::R14) {
    DEBUG(dbgs() << "Creating store funclet.\n");
    // BL to __save_r13_to_<TRI->getRegAsmName()>
    StackSlotsUsedByFunclet = Last - ARC::R12;
    BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
    BuildMI(MBB, MBBI, dl, TII->get(ARC::SUB_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(4 * StackSlotsUsedByFunclet);
    BuildMI(MBB, MBBI, dl, TII->get(ARC::BL))
        .addExternalSymbol(store_funclet_name[Last - ARC::R15])
        .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
    AlreadyAdjusted += 4 * (StackSlotsUsedByFunclet + 1);
    SavedBlink = true;
  }
  // If we haven't saved BLINK, but we need to...do that now.
  if (MFI.hasCalls() && !SavedBlink) {
    DEBUG(dbgs() << "Creating save blink.\n");
    BuildMI(MBB, MBBI, dl, TII->get(ARC::PUSH_S_BLINK));
    AlreadyAdjusted += 4;
  }
  if (AFI->MaxCallStackReq > 0)
    MFI.setStackSize(MFI.getStackSize() + AFI->MaxCallStackReq);
  // We have already saved some of the stack...
  DEBUG(dbgs() << "Adjusting stack by: "
               << (MFI.getStackSize() - AlreadyAdjusted) << "\n");
  generateStackAdjustment(MBB, MBBI, *ST.getInstrInfo(), dl,
                          -(MFI.getStackSize() - AlreadyAdjusted), ARC::SP);

  if (hasFP(MF)) {
    DEBUG(dbgs() << "Setting FP from SP.\n");
    BuildMI(MBB, MBBI, dl,
            TII->get(isUInt<6>(MFI.getStackSize()) ? ARC::ADD_rru6
                                                   : ARC::ADD_rrlimm),
            ARC::FP)
        .addReg(ARC::SP)
        .addImm(MFI.getStackSize());
  }

  // Emit CFI records:
  // .cfi_def_cfa_offset StackSize
  // .cfi_offset fp, -StackSize
  // .cfi_offset blink, -StackSize+4
  unsigned CFIIndex = MF.addFrameInst(
      MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize()));
  BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
      .addCFIIndex(CFIIndex)
      .setMIFlags(MachineInstr::FrameSetup);

  int CurOffset = -4;
  if (hasFP(MF)) {
    CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
        nullptr, MRI->getDwarfRegNum(ARC::FP, true), CurOffset));
    BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex)
        .setMIFlags(MachineInstr::FrameSetup);
    CurOffset -= 4;
  }

  if (MFI.hasCalls()) {
    CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
        nullptr, MRI->getDwarfRegNum(ARC::BLINK, true), CurOffset));
    BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex)
        .setMIFlags(MachineInstr::FrameSetup);
  }
  // CFI for the rest of the registers.
  for (const auto &Entry : CSI) {
    unsigned Reg = Entry.getReg();
    int FI = Entry.getFrameIdx();
    // Skip BLINK and FP.
    if ((hasFP(MF) && Reg == ARC::FP) || (MFI.hasCalls() && Reg == ARC::BLINK))
      continue;
    CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
        nullptr, MRI->getDwarfRegNum(Reg, true), MFI.getObjectOffset(FI)));
    BuildMI(MBB, MBBI, dl, TII->get(TargetOpcode::CFI_INSTRUCTION))
        .addCFIIndex(CFIIndex)
        .setMIFlags(MachineInstr::FrameSetup);
  }
}

/// Insert epilog code into the function.
/// For ARC, this inserts a call to a function that restores callee saved
/// registers onto the stack, when enough callee saved registers are required.
void ARCFrameLowering::emitEpilogue(MachineFunction &MF,
                                    MachineBasicBlock &MBB) const {
  DEBUG(dbgs() << "Emit Epilogue: " << MF.getFunction()->getName() << "\n");
  auto *AFI = MF.getInfo<ARCFunctionInfo>();
  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
  MachineBasicBlock::iterator MBBI = MBB.getFirstTerminator();
  MachineFrameInfo &MFI = MF.getFrameInfo();
  uint64_t StackSize = MF.getFrameInfo().getStackSize();
  bool SavedBlink = false;
  unsigned AmountAboveFunclet = 0;
  // If we have variable sized frame objects, then we have to move
  // the stack pointer to a known spot (fp - StackSize).
  // Then, replace the frame pointer by (new) [sp,StackSize-4].
  // Then, move the stack pointer the rest of the way (sp = sp + StackSize).
  if (hasFP(MF)) {
    BuildMI(MBB, MBBI, DebugLoc(), TII->get(ARC::SUB_rru6), ARC::SP)
        .addReg(ARC::FP)
        .addImm(StackSize);
    AmountAboveFunclet += 4;
  }

  // Now, move the stack pointer to the bottom of the save area for the funclet.
  const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
  unsigned Last = determineLastCalleeSave(CSI);
  unsigned StackSlotsUsedByFunclet = 0;
  // Now, restore the callee save registers.
  if (UseSaveRestoreFunclet && Last > ARC::R14) {
    // BL to __ld_r13_to_<TRI->getRegAsmName()>
    StackSlotsUsedByFunclet = Last - ARC::R12;
    AmountAboveFunclet += 4 * (StackSlotsUsedByFunclet + 1);
    SavedBlink = true;
  }

  if (MFI.hasCalls() && !SavedBlink) {
    AmountAboveFunclet += 4;
    SavedBlink = true;
  }

  // Move the stack pointer up to the point of the funclet.
  if (StackSize - AmountAboveFunclet) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(StackSize - AmountAboveFunclet);
  }

  if (StackSlotsUsedByFunclet) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::BL))
        .addExternalSymbol(load_funclet_name[Last - ARC::R15])
        .addReg(ARC::BLINK, RegState::Implicit | RegState::Kill);
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(4 * (StackSlotsUsedByFunclet));
  }
  // Now, pop blink if necessary.
  if (SavedBlink) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::POP_S_BLINK));
  }
  // Now, pop fp if necessary.
  if (hasFP(MF)) {
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::LD_AB_rs9))
        .addReg(ARC::SP, RegState::Define)
        .addReg(ARC::FP, RegState::Define)
        .addReg(ARC::SP)
        .addImm(4);
  }

  // Relieve the varargs area if necessary.
  if (MF.getFunction()->isVarArg()) {
    // Add in the varargs area here first.
    DEBUG(dbgs() << "Varargs\n");
    unsigned VarArgsBytes = MFI.getObjectSize(AFI->getVarArgsFrameIndex());
    BuildMI(MBB, MBBI, MBB.findDebugLoc(MBBI), TII->get(ARC::ADD_rru6))
        .addReg(ARC::SP)
        .addReg(ARC::SP)
        .addImm(VarArgsBytes);
  }
}

static std::vector<CalleeSavedInfo>::iterator
getSavedReg(std::vector<CalleeSavedInfo> &V, unsigned reg) {
  for (auto I = V.begin(), E = V.end(); I != E; ++I) {
    if (reg == I->getReg())
      return I;
  }
  return V.end();
}

bool ARCFrameLowering::assignCalleeSavedSpillSlots(
    MachineFunction &MF, const TargetRegisterInfo *TRI,
    std::vector<CalleeSavedInfo> &CSI) const {
  // Use this opportunity to assign the spill slots for all of the potential
  // callee save registers (blink, fp, r13->r25) that we care about the
  // placement for.  We can calculate all of that data here.
  int CurOffset = -4;
  unsigned Last = determineLastCalleeSave(CSI);
  MachineFrameInfo &MFI = MF.getFrameInfo();
  if (hasFP(MF)) {
    // Create a fixed slot at for FP
    int StackObj = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
    DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for FP at "
                 << CurOffset << "\n");
    (void)StackObj;
    CurOffset -= 4;
  }
  if (MFI.hasCalls() || (UseSaveRestoreFunclet && Last > ARC::R14)) {
    // Create a fixed slot for BLINK.
    int StackObj  = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
    DEBUG(dbgs() << "Creating fixed object (" << StackObj << ") for BLINK at "
                 << CurOffset << "\n");
    (void)StackObj;
    CurOffset -= 4;
  }

  // Create slots for last down to r13.
  for (unsigned Which = Last; Which > ARC::R12; Which--) {
    auto RegI = getSavedReg(CSI, Which);
    if (RegI == CSI.end() || RegI->getFrameIdx() == 0) {
      // Always create the stack slot.  If for some reason the register isn't in
      // the save list, then don't worry about it.
      int FI = MFI.CreateFixedSpillStackObject(4, CurOffset, true);
      if (RegI != CSI.end())
        RegI->setFrameIdx(FI);
    } else
      MFI.setObjectOffset(RegI->getFrameIdx(), CurOffset);
    CurOffset -= 4;
  }
  for (auto &I : CSI) {
    if (I.getReg() > ARC::R12)
      continue;
    if (I.getFrameIdx() == 0) {
      I.setFrameIdx(MFI.CreateFixedSpillStackObject(4, CurOffset, true));
      DEBUG(dbgs() << "Creating fixed object (" << I.getFrameIdx()
                   << ") for other register at " << CurOffset << "\n");
    } else {
      MFI.setObjectOffset(I.getFrameIdx(), CurOffset);
      DEBUG(dbgs() << "Updating fixed object (" << I.getFrameIdx()
                   << ") for other register at " << CurOffset << "\n");
    }
    CurOffset -= 4;
  }
  return true;
}

bool ARCFrameLowering::spillCalleeSavedRegisters(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
    const std::vector<CalleeSavedInfo> &CSI,
    const TargetRegisterInfo *TRI) const {
  DEBUG(dbgs() << "Spill callee saved registers: "
               << MBB.getParent()->getFunction()->getName() << "\n");
  // There are routines for saving at least 3 registers (r13 to r15, etc.)
  unsigned Last = determineLastCalleeSave(CSI);
  if (UseSaveRestoreFunclet && Last > ARC::R14) {
    // Use setObjectOffset for these registers.
    // Needs to be in or before processFunctionBeforeFrameFinalized.
    // Or, do assignCalleeSaveSpillSlots?
    // Will be handled in prolog.
    return true;
  }
  return false;
}

bool ARCFrameLowering::restoreCalleeSavedRegisters(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
    std::vector<CalleeSavedInfo> &CSI, const TargetRegisterInfo *TRI) const {
  DEBUG(dbgs() << "Restore callee saved registers: "
               << MBB.getParent()->getFunction()->getName() << "\n");
  // There are routines for saving at least 3 registers (r13 to r15, etc.)
  unsigned Last = determineLastCalleeSave(CSI);
  if (UseSaveRestoreFunclet && Last > ARC::R14) {
    // Will be handled in epilog.
    return true;
  }
  return false;
}

// Adjust local variables that are 4-bytes or larger to 4-byte boundary
void ARCFrameLowering::processFunctionBeforeFrameFinalized(
    MachineFunction &MF, RegScavenger *RS) const {
  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
  DEBUG(dbgs() << "Process function before frame finalized: "
               << MF.getFunction()->getName() << "\n");
  MachineFrameInfo &MFI = MF.getFrameInfo();
  DEBUG(dbgs() << "Current stack size: " << MFI.getStackSize() << "\n");
  const TargetRegisterClass *RC = &ARC::GPR32RegClass;
  if (MFI.hasStackObjects()) {
    int RegScavFI = MFI.CreateStackObject(
        RegInfo->getSpillSize(*RC), RegInfo->getSpillAlignment(*RC), false);
    RS->addScavengingFrameIndex(RegScavFI);
    DEBUG(dbgs() << "Created scavenging index RegScavFI=" << RegScavFI << "\n");
  }
}

static void emitRegUpdate(MachineBasicBlock &MBB,
                          MachineBasicBlock::iterator &MBBI, DebugLoc dl,
                          unsigned Reg, int NumBytes, bool IsAdd,
                          const ARCInstrInfo *TII) {
  unsigned Opc = IsAdd ? ARC::ADD_rru6 : ARC::SUB_rru6;
  BuildMI(MBB, MBBI, dl, TII->get(Opc), Reg)
      .addReg(Reg, RegState::Kill)
      .addImm(NumBytes);
}

MachineBasicBlock::iterator ARCFrameLowering::eliminateCallFramePseudoInstr(
    MachineFunction &MF, MachineBasicBlock &MBB,
    MachineBasicBlock::iterator I) const {
  DEBUG(dbgs() << "EmitCallFramePseudo: " << MF.getFunction()->getName()
               << "\n");
  const ARCInstrInfo *TII = MF.getSubtarget<ARCSubtarget>().getInstrInfo();
  MachineInstr &Old = *I;
  DebugLoc dl = Old.getDebugLoc();
  unsigned Amt = Old.getOperand(0).getImm();
  auto *AFI = MF.getInfo<ARCFunctionInfo>();
  if (!hasFP(MF)) {
    if (Amt > AFI->MaxCallStackReq && Old.getOpcode() == ARC::ADJCALLSTACKDOWN)
      AFI->MaxCallStackReq = Amt;
  } else {
    if (Amt != 0) {
      assert((Old.getOpcode() == ARC::ADJCALLSTACKDOWN ||
              Old.getOpcode() == ARC::ADJCALLSTACKUP) &&
             "Unknown Frame Pseudo.");
      bool IsAdd = (Old.getOpcode() == ARC::ADJCALLSTACKUP);
      emitRegUpdate(MBB, I, dl, ARC::SP, Amt, IsAdd, TII);
    }
  }
  return MBB.erase(I);
}

bool ARCFrameLowering::hasFP(const MachineFunction &MF) const {
  const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
  bool HasFP = MF.getTarget().Options.DisableFramePointerElim(MF) ||
               MF.getFrameInfo().hasVarSizedObjects() ||
               MF.getFrameInfo().isFrameAddressTaken() ||
               RegInfo->needsStackRealignment(MF);
  return HasFP;
}
