mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-21 12:38:45 +00:00
Add prologue/epilogue emission. Fix frame pointer handling.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70740 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d5047cb9f7
commit
ce45d30fa1
@ -14,6 +14,7 @@
|
|||||||
#define DEBUG_TYPE "msp430-reg-info"
|
#define DEBUG_TYPE "msp430-reg-info"
|
||||||
|
|
||||||
#include "MSP430.h"
|
#include "MSP430.h"
|
||||||
|
#include "MSP430MachineFunctionInfo.h"
|
||||||
#include "MSP430RegisterInfo.h"
|
#include "MSP430RegisterInfo.h"
|
||||||
#include "MSP430TargetMachine.h"
|
#include "MSP430TargetMachine.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
@ -165,12 +166,14 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
unsigned BasePtr = (hasFP(MF) ? MSP430::FPW : MSP430::SPW);
|
unsigned BasePtr = (hasFP(MF) ? MSP430::FPW : MSP430::SPW);
|
||||||
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
|
int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex);
|
||||||
|
|
||||||
if (!hasFP(MF))
|
|
||||||
Offset += MF.getFrameInfo()->getStackSize();
|
|
||||||
|
|
||||||
// Skip the saved PC
|
// Skip the saved PC
|
||||||
Offset += 2;
|
Offset += 2;
|
||||||
|
|
||||||
|
if (!hasFP(MF))
|
||||||
|
Offset += MF.getFrameInfo()->getStackSize();
|
||||||
|
else
|
||||||
|
Offset += 2; // Skip the saved FPW
|
||||||
|
|
||||||
// Fold imm into offset
|
// Fold imm into offset
|
||||||
Offset += MI.getOperand(i+1).getImm();
|
Offset += MI.getOperand(i+1).getImm();
|
||||||
|
|
||||||
@ -201,13 +204,140 @@ MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
|||||||
MI.getOperand(i+1).ChangeToImmediate(Offset);
|
MI.getOperand(i+1).ChangeToImmediate(Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MSP430RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF)
|
||||||
|
const {
|
||||||
|
// Create a frame entry for the FPW register that must be saved.
|
||||||
|
if (hasFP(MF)) {
|
||||||
|
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4);
|
||||||
|
assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&
|
||||||
|
"Slot for FPW register must be last in order to be found!");
|
||||||
|
FrameIdx = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void MSP430RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
void MSP430RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
||||||
// Nothing here yet
|
MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
|
||||||
|
MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
|
||||||
|
MachineBasicBlock::iterator MBBI = MBB.begin();
|
||||||
|
DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() :
|
||||||
|
DebugLoc::getUnknownLoc());
|
||||||
|
|
||||||
|
// Get the number of bytes to allocate from the FrameInfo.
|
||||||
|
uint64_t StackSize = MFI->getStackSize();
|
||||||
|
|
||||||
|
uint64_t NumBytes = 0;
|
||||||
|
if (hasFP(MF)) {
|
||||||
|
// Calculate required stack adjustment
|
||||||
|
uint64_t FrameSize = StackSize - 2;
|
||||||
|
NumBytes = FrameSize - MSP430FI->getCalleeSavedFrameSize();
|
||||||
|
|
||||||
|
// Get the offset of the stack slot for the EBP register... which is
|
||||||
|
// guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
|
||||||
|
// Update the frame offset adjustment.
|
||||||
|
MFI->setOffsetAdjustment(-NumBytes);
|
||||||
|
|
||||||
|
// Save FPW into the appropriate stack slot...
|
||||||
|
BuildMI(MBB, MBBI, DL, TII.get(MSP430::PUSH16r))
|
||||||
|
.addReg(MSP430::FPW, /*isDef=*/false, /*isImp=*/false, /*isKill=*/true);
|
||||||
|
|
||||||
|
// Update FPW with the new base value...
|
||||||
|
BuildMI(MBB, MBBI, DL, TII.get(MSP430::MOV16rr), MSP430::FPW)
|
||||||
|
.addReg(MSP430::SPW);
|
||||||
|
|
||||||
|
// Mark the FramePtr as live-in in every block except the entry.
|
||||||
|
for (MachineFunction::iterator I = next(MF.begin()), E = MF.end();
|
||||||
|
I != E; ++I)
|
||||||
|
I->addLiveIn(MSP430::FPW);
|
||||||
|
|
||||||
|
} else
|
||||||
|
NumBytes = StackSize - MSP430FI->getCalleeSavedFrameSize();
|
||||||
|
|
||||||
|
// Skip the callee-saved push instructions.
|
||||||
|
while (MBBI != MBB.end() && (MBBI->getOpcode() == MSP430::PUSH16r))
|
||||||
|
++MBBI;
|
||||||
|
|
||||||
|
if (MBBI != MBB.end())
|
||||||
|
DL = MBBI->getDebugLoc();
|
||||||
|
|
||||||
|
if (NumBytes) { // adjust stack pointer: SPW -= numbytes
|
||||||
|
// If there is an SUB16ri of SPW immediately before this instruction, merge
|
||||||
|
// the two.
|
||||||
|
//NumBytes -= mergeSPUpdates(MBB, MBBI, true);
|
||||||
|
// If there is an ADD16ri or SUB16ri of SPW immediately after this
|
||||||
|
// instruction, merge the two instructions.
|
||||||
|
// mergeSPUpdatesDown(MBB, MBBI, &NumBytes);
|
||||||
|
|
||||||
|
if (NumBytes) {
|
||||||
|
MachineInstr *MI =
|
||||||
|
BuildMI(MBB, MBBI, DL, TII.get(MSP430::SUB16ri), MSP430::SPW)
|
||||||
|
.addReg(MSP430::SPW).addImm(NumBytes);
|
||||||
|
// The SRW implicit def is dead.
|
||||||
|
MI->getOperand(3).setIsDead();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF,
|
void MSP430RegisterInfo::emitEpilogue(MachineFunction &MF,
|
||||||
MachineBasicBlock &MBB) const {
|
MachineBasicBlock &MBB) const {
|
||||||
// Nothing here yet
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
|
MSP430MachineFunctionInfo *MSP430FI = MF.getInfo<MSP430MachineFunctionInfo>();
|
||||||
|
MachineBasicBlock::iterator MBBI = prior(MBB.end());
|
||||||
|
unsigned RetOpcode = MBBI->getOpcode();
|
||||||
|
DebugLoc DL = MBBI->getDebugLoc();
|
||||||
|
|
||||||
|
switch (RetOpcode) {
|
||||||
|
case MSP430::RET: break; // These are ok
|
||||||
|
default:
|
||||||
|
assert(0 && "Can only insert epilog into returning blocks");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the number of bytes to allocate from the FrameInfo
|
||||||
|
uint64_t StackSize = MFI->getStackSize();
|
||||||
|
unsigned CSSize = MSP430FI->getCalleeSavedFrameSize();
|
||||||
|
uint64_t NumBytes = 0;
|
||||||
|
|
||||||
|
if (hasFP(MF)) {
|
||||||
|
// Calculate required stack adjustment
|
||||||
|
uint64_t FrameSize = StackSize - 2;
|
||||||
|
NumBytes = FrameSize - CSSize;
|
||||||
|
|
||||||
|
// pop FPW.
|
||||||
|
BuildMI(MBB, MBBI, DL, TII.get(MSP430::POP16r), MSP430::FPW);
|
||||||
|
} else
|
||||||
|
NumBytes = StackSize - CSSize;
|
||||||
|
|
||||||
|
// Skip the callee-saved pop instructions.
|
||||||
|
MachineBasicBlock::iterator LastCSPop = MBBI;
|
||||||
|
while (MBBI != MBB.begin()) {
|
||||||
|
MachineBasicBlock::iterator PI = prior(MBBI);
|
||||||
|
unsigned Opc = PI->getOpcode();
|
||||||
|
if (Opc != MSP430::POP16r && !PI->getDesc().isTerminator())
|
||||||
|
break;
|
||||||
|
--MBBI;
|
||||||
|
}
|
||||||
|
|
||||||
|
DL = MBBI->getDebugLoc();
|
||||||
|
|
||||||
|
// If there is an ADD16ri or SUB16ri of SPW immediately before this
|
||||||
|
// instruction, merge the two instructions.
|
||||||
|
//if (NumBytes || MFI->hasVarSizedObjects())
|
||||||
|
// mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
|
||||||
|
|
||||||
|
if (MFI->hasVarSizedObjects()) {
|
||||||
|
assert(0 && "Not implemented yet!");
|
||||||
|
} else {
|
||||||
|
// adjust stack pointer back: SPW += numbytes
|
||||||
|
if (NumBytes) {
|
||||||
|
MachineInstr *MI =
|
||||||
|
BuildMI(MBB, MBBI, DL, TII.get(MSP430::ADD16ri), MSP430::SPW)
|
||||||
|
.addReg(MSP430::SPW).addImm(NumBytes);
|
||||||
|
// The SRW implicit def is dead.
|
||||||
|
MI->getOperand(3).setIsDead();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned MSP430RegisterInfo::getRARegister() const {
|
unsigned MSP430RegisterInfo::getRARegister() const {
|
||||||
|
@ -55,6 +55,8 @@ public:
|
|||||||
void emitPrologue(MachineFunction &MF) const;
|
void emitPrologue(MachineFunction &MF) const;
|
||||||
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
|
||||||
|
|
||||||
|
void processFunctionBeforeFrameFinalized(MachineFunction &MF) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
unsigned getRARegister() const;
|
unsigned getRARegister() const;
|
||||||
unsigned getFrameRegister(MachineFunction &MF) const;
|
unsigned getFrameRegister(MachineFunction &MF) const;
|
||||||
|
@ -41,7 +41,7 @@ MSP430TargetMachine::MSP430TargetMachine(const Module &M,
|
|||||||
// FIXME: Check TargetData string.
|
// FIXME: Check TargetData string.
|
||||||
DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"),
|
DataLayout("e-p:16:8:8-i8:8:8-i16:8:8-i32:8:8"),
|
||||||
InstrInfo(*this), TLInfo(*this),
|
InstrInfo(*this), TLInfo(*this),
|
||||||
FrameInfo(TargetFrameInfo::StackGrowsDown, 8, 0) { }
|
FrameInfo(TargetFrameInfo::StackGrowsDown, 2, -2) { }
|
||||||
|
|
||||||
const TargetAsmInfo *MSP430TargetMachine::createTargetAsmInfo() const {
|
const TargetAsmInfo *MSP430TargetMachine::createTargetAsmInfo() const {
|
||||||
return new MSP430TargetAsmInfo(*this);
|
return new MSP430TargetAsmInfo(*this);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user