151 lines
5.0 KiB
C++
151 lines
5.0 KiB
C++
#include "FootFrameLowering.h"
|
|
|
|
#include "FootMachineFunctionInfo.h"
|
|
#include "MCTargetDesc/FootMCTargetDesc.h"
|
|
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
#include "llvm/CodeGen/TargetInstrInfo.h"
|
|
#include "llvm/CodeGen/TargetSubtargetInfo.h"
|
|
#include "llvm/MC/MCDwarf.h"
|
|
|
|
using namespace llvm;
|
|
|
|
bool FootFrameLowering::hasFPImpl(const MachineFunction &MF) const {
|
|
return true;
|
|
}
|
|
|
|
void FootFrameLowering::emitPrologue(MachineFunction &MF,
|
|
MachineBasicBlock &MBB) const {
|
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
|
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
|
|
|
int FI = MF.getInfo<FootMachineFunctionInfo>()->getReturnAddressFrameIndex();
|
|
|
|
unsigned int CFIIndex =
|
|
MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(
|
|
nullptr, MF.getRegInfo().getTargetRegisterInfo()->getDwarfRegNum(
|
|
Foot::RSP, true)));
|
|
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(TargetOpcode::CFI_INSTRUCTION))
|
|
.addCFIIndex(CFIIndex);
|
|
|
|
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::BWOR_I_D_M_A))
|
|
.addFrameIndex(FI)
|
|
.addReg(Foot::RRA)
|
|
.addImm(0);
|
|
unsigned int RRADwarfRegNum =
|
|
MF.getRegInfo().getTargetRegisterInfo()->getDwarfRegNum(Foot::RRA, false);
|
|
int Offset = MFI.getObjectOffset(FI);
|
|
CFIIndex = MF.addFrameInst(
|
|
MCCFIInstruction::createOffset(nullptr, RRADwarfRegNum, Offset));
|
|
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(TargetOpcode::CFI_INSTRUCTION))
|
|
.addCFIIndex(CFIIndex);
|
|
|
|
unsigned NumBytes = MFI.getStackSize();
|
|
|
|
if (NumBytes > 0) {
|
|
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
|
|
|
if (NumBytes < (1 << 5)) {
|
|
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_M_A),
|
|
Foot::RSP)
|
|
.addReg(Foot::RSP)
|
|
.addImm(NumBytes);
|
|
} else {
|
|
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::SUBT_D_D_D_A),
|
|
Foot::RSP)
|
|
.addReg(Foot::RSP)
|
|
.addReg(Foot::R27);
|
|
BuildMI(MBB, MBB.begin(), DebugLoc(), TII->get(Foot::CNST_D_A), Foot::R27)
|
|
.addImm(NumBytes);
|
|
}
|
|
|
|
CFIIndex = MF.addFrameInst(
|
|
MCCFIInstruction::createAdjustCfaOffset(nullptr, NumBytes));
|
|
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
|
TII->get(TargetOpcode::CFI_INSTRUCTION))
|
|
.addCFIIndex(CFIIndex);
|
|
}
|
|
}
|
|
|
|
void FootFrameLowering::emitEpilogue(MachineFunction &MF,
|
|
MachineBasicBlock &MBB) const {
|
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
|
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
|
|
|
unsigned NumBytes = MFI.getStackSize();
|
|
|
|
int FI = MF.getInfo<FootMachineFunctionInfo>()->getReturnAddressFrameIndex();
|
|
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
|
TII->get(Foot::BWOR_D_I_M_A))
|
|
.addReg(Foot::RRA)
|
|
.addFrameIndex(FI)
|
|
.addImm(0);
|
|
|
|
if (NumBytes > 0) {
|
|
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
|
if (NumBytes < (1 << 5)) {
|
|
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
|
TII->get(Foot::ADDI_D_D_M_A), Foot::RSP)
|
|
.addReg(Foot::RSP)
|
|
.addImm(NumBytes);
|
|
} else {
|
|
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
|
TII->get(Foot::ADDI_D_D_D_A), Foot::RSP)
|
|
.addReg(Foot::RSP)
|
|
.addReg(Foot::R27);
|
|
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
|
TII->get(Foot::CNST_D_A), Foot::R27)
|
|
.addImm(NumBytes);
|
|
}
|
|
|
|
unsigned int CFIIndex =
|
|
MF.addFrameInst(MCCFIInstruction::createAdjustCfaOffset(nullptr, 0));
|
|
BuildMI(MBB, MBB.getFirstTerminator(), DebugLoc(),
|
|
TII->get(TargetOpcode::CFI_INSTRUCTION))
|
|
.addCFIIndex(CFIIndex);
|
|
}
|
|
|
|
const auto &I = MBB.getFirstTerminator();
|
|
BuildMI(MBB, MBB.getFirstTerminator(), I->getDebugLoc(),
|
|
TII->get(Foot::COPY_D_D_A))
|
|
.addReg(Foot::RPC)
|
|
.addReg(Foot::RRA);
|
|
|
|
MBB.erase(I);
|
|
}
|
|
|
|
MachineBasicBlock::iterator FootFrameLowering::eliminateCallFramePseudoInstr(
|
|
MachineFunction &MF, MachineBasicBlock &MBB,
|
|
MachineBasicBlock::iterator MI) const {
|
|
const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo();
|
|
unsigned Opc = MI->getOpcode();
|
|
|
|
assert(hasReservedCallFrame(MF) && "Foot doesn't have an FP register");
|
|
|
|
if (Opc != TII->getCallFrameSetupOpcode() &&
|
|
Opc != TII->getCallFrameDestroyOpcode()) {
|
|
report_fatal_error("Unexpected frame psuedo instruction");
|
|
}
|
|
|
|
if (MI->getOperand(1).getImm() != 0) {
|
|
report_fatal_error("callee pop count not supported");
|
|
}
|
|
|
|
return MBB.erase(MI);
|
|
}
|
|
|
|
void FootFrameLowering::determineCalleeSaves(MachineFunction &MF,
|
|
BitVector &SavedRegs,
|
|
RegScavenger *RS) const {
|
|
TargetFrameLowering::determineCalleeSaves(MF, SavedRegs, RS);
|
|
|
|
SavedRegs.set(Foot::RSP);
|
|
SavedRegs.set(Foot::RRA);
|
|
|
|
MachineFrameInfo &MFI = MF.getFrameInfo();
|
|
|
|
int RetAddrFI = MFI.CreateStackObject(4, Align(4), false);
|
|
|
|
MF.getInfo<FootMachineFunctionInfo>()->setReturnAddressFrameIndex(RetAddrFI);
|
|
}
|