So I am trying to implement a Toy Backend using LLVM using the below codes as reference for the different steps
I have a rough idea as to what frame lowering is (read emit prologue and emit epilogue) below are the codes for the same from the reference that I am using
emitPrologue:
void TOYFrameLowering::emitPrologue(MachineFunction &MF) const {
const TargetInstrInfo &TII =*MF.getSubtarget().getInstrInfo();
MachineBasicBlock &MBB = MF.front();
MachineBasicBlock::iterator MBBI = MBB.begin();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() :DebugLoc();
uint64_t StackSize = computeStackSize(MF);
if (!StackSize) {
return;
}
unsigned StackReg = TOY::SP; //stack pointer
unsigned OffsetReg = materializeOffset(MF, MBB, MBBI,
(unsigned)StackSize);
if (OffsetReg) {
BuildMI(MBB, MBBI, dl, TII.get(TOY::SUBrr), StackReg)
.addReg(StackReg)
.addReg(OffsetReg)
.setMIFlag(MachineInstr::FrameSetup);
} else {
BuildMI(MBB, MBBI, dl, TII.get(TOY::SUBri), StackReg)
.addReg(StackReg)
.addImm(StackSize)
.setMIFlag(MachineInstr::FrameSetup);
}
}
emitEpilogue:
void TOYFrameLowering::emitEpilogue(MachineFunction &MF,MachineBasicBlock &MBB)const {
const TargetInstrInfo &TII =*MF.getSubtarget().getInstrInfo();
MachineBasicBlock::iterator MBBI =MBB.getLastNonDebugInstr();
DebugLoc dl = MBBI->getDebugLoc();
uint64_t StackSize = computeStackSize(MF);
if (!StackSize) {
return;
}
unsigned StackReg = TOY::SP;
unsigned OffsetReg = materializeOffset(MF, MBB, MBBI,(unsigned)StackSize);
if (OffsetReg) {
BuildMI(MBB, MBBI, dl, TII.get(TOY::ADDrr), StackReg)
.addReg(StackReg)
.addReg(OffsetReg)
.setMIFlag(MachineInstr::FrameSetup);
}
else {
BuildMI(MBB, MBBI, dl, TII.get(TOY::ADDri), StackReg)
.addReg(StackReg)
.addImm(StackSize)
.setMIFlag(MachineInstr::FrameSetup);
}
}
Some helper Functions:
compute stack size:
uint64_t TOYFrameLowering::computeStackSize(MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();
uint64_t StackSize = MFI->getStackSize();
unsigned StackAlign = getStackAlignment();
if (StackAlign > 0) {
StackSize = RoundUpToAlignment(StackSize, StackAlign);
}
return StackSize;
}
materialize offset:
static unsigned materializeOffset(MachineFunction &MF,MachineBasicBlock &MBB,MachineBasicBlock::iterator MBBI,unsigned Offset) {
const TargetInstrInfo &TII =*MF.getSubtarget().getInstrInfo();
DebugLoc dl = MBBI != MBB.end() ? MBBI->getDebugLoc() : DebugLoc();
const uint64_t MaxSubImm = 0xfff;
if (Offset <= MaxSubImm) {
return 0;
}
else {
unsigned OffsetReg = TOY::R2;
unsigned OffsetLo = (unsigned)(Offset & 0xffff);
unsigned OffsetHi = (unsigned)((Offset & 0xffff0000) >>16);
BuildMI(MBB, MBBI, dl, TII.get(TOY::MOVLOi16),OffsetReg)
.addImm(OffsetLo)
.setMIFlag(MachineInstr::FrameSetup);
if (OffsetHi) {
BuildMI(MBB, MBBI, dl, TII.get(TOY::MOVHIi16),OffsetReg)
.addReg(OffsetReg)
.addImm(OffsetHi)
.setMIFlag(MachineInstr::FrameSetup);
}
return OffsetReg;
}
}
Everything is pretty self-explanatory except the materializeoffset() function I cannot seem to wrap my head around as to what it does can someone explain the same using an example
User contributions licensed under CC BY-SA 3.0