#include "LanaiFrameLowering.h"
#include "LanaiAluCode.h"
#include "LanaiInstrInfo.h"
#include "LanaiSubtarget.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h"
using namespace llvm;
void LanaiFrameLowering::determineFrameLayout(MachineFunction &MF) const {
MachineFrameInfo &MFI = MF.getFrameInfo();
const LanaiRegisterInfo *LRI = STI.getRegisterInfo();
unsigned FrameSize = MFI.getStackSize();
Align StackAlign =
LRI->hasStackRealignment(MF) ? MFI.getMaxAlign() : getStackAlign();
unsigned MaxCallFrameSize = MFI.getMaxCallFrameSize();
if (MFI.hasVarSizedObjects())
MaxCallFrameSize = alignTo(MaxCallFrameSize, StackAlign);
MFI.setMaxCallFrameSize(MaxCallFrameSize);
if (!(hasReservedCallFrame(MF) && MFI.adjustsStack()))
FrameSize += MaxCallFrameSize;
FrameSize = alignTo(FrameSize, StackAlign);
MFI.setStackSize(FrameSize);
}
void LanaiFrameLowering::replaceAdjDynAllocPseudo(MachineFunction &MF) const {
const LanaiInstrInfo &LII =
*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
unsigned MaxCallFrameSize = MF.getFrameInfo().getMaxCallFrameSize();
for (MachineBasicBlock &MBB : MF) {
for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
if (MI.getOpcode() == Lanai::ADJDYNALLOC) {
DebugLoc DL = MI.getDebugLoc();
Register Dst = MI.getOperand(0).getReg();
Register Src = MI.getOperand(1).getReg();
BuildMI(MBB, MI, DL, LII.get(Lanai::ADD_I_LO), Dst)
.addReg(Src)
.addImm(MaxCallFrameSize);
MI.eraseFromParent();
}
}
}
}
void LanaiFrameLowering::emitPrologue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
assert(&MF.front() == &MBB && "Shrink-wrapping not yet supported");
MachineFrameInfo &MFI = MF.getFrameInfo();
const LanaiInstrInfo &LII =
*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc DL;
determineFrameLayout(MF);
unsigned StackSize = MFI.getStackSize();
BuildMI(MBB, MBBI, DL, LII.get(Lanai::SW_RI))
.addReg(Lanai::FP)
.addReg(Lanai::SP)
.addImm(-4)
.addImm(LPAC::makePreOp(LPAC::ADD))
.setMIFlag(MachineInstr::FrameSetup);
BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::FP)
.addReg(Lanai::SP)
.addImm(8)
.setMIFlag(MachineInstr::FrameSetup);
if (StackSize != 0) {
BuildMI(MBB, MBBI, DL, LII.get(Lanai::SUB_I_LO), Lanai::SP)
.addReg(Lanai::SP)
.addImm(StackSize)
.setMIFlag(MachineInstr::FrameSetup);
}
if (MFI.hasVarSizedObjects())
replaceAdjDynAllocPseudo(MF);
}
MachineBasicBlock::iterator LanaiFrameLowering::eliminateCallFramePseudoInstr(
MachineFunction & , MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
return MBB.erase(I);
}
void LanaiFrameLowering::emitEpilogue(MachineFunction & ,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
const LanaiInstrInfo &LII =
*static_cast<const LanaiInstrInfo *>(STI.getInstrInfo());
DebugLoc DL = MBBI->getDebugLoc();
BuildMI(MBB, MBBI, DL, LII.get(Lanai::ADD_I_LO), Lanai::SP)
.addReg(Lanai::FP)
.addImm(0);
BuildMI(MBB, MBBI, DL, LII.get(Lanai::LDW_RI), Lanai::FP)
.addReg(Lanai::FP)
.addImm(-8)
.addImm(LPAC::ADD);
}
void LanaiFrameLowering::determineCalleeSaves(MachineFunction &MF,
BitVector &SavedRegs,
RegScavenger *RS) const {
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
MachineFrameInfo &MFI = MF.getFrameInfo();
const LanaiRegisterInfo *LRI =
static_cast<const LanaiRegisterInfo *>(STI.getRegisterInfo());
int Offset = -4;
MFI.CreateFixedObject(4, Offset, true);
Offset -= 4;
MFI.CreateFixedObject(4, Offset, true);
Offset -= 4;
if (LRI->hasBasePointer(MF)) {
MFI.CreateFixedObject(4, Offset, true);
SavedRegs.reset(LRI->getBaseRegister());
}
}