mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-15 07:34:33 +00:00
In thumb mode, round up stack frame size to multiple of 4 since add/sub
sp, imm instructions implicitly multiply the offset by 4. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33653 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
5b91c7f69a
commit
236f677e48
@ -884,93 +884,100 @@ void ARMRegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
unsigned NumBytes = MFI->getStackSize();
|
unsigned NumBytes = MFI->getStackSize();
|
||||||
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
|
const std::vector<CalleeSavedInfo> &CSI = MFI->getCalleeSavedInfo();
|
||||||
|
|
||||||
|
if (isThumb) {
|
||||||
|
// Thumb add/sub sp, imm8 instructions implicitly multiply the offset by 4.
|
||||||
|
NumBytes = (NumBytes + 3) & ~3;
|
||||||
|
MFI->setStackSize(NumBytes);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the sizes of each callee-save spill areas and record which frame
|
// Determine the sizes of each callee-save spill areas and record which frame
|
||||||
// belongs to which callee-save spill areas.
|
// belongs to which callee-save spill areas.
|
||||||
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
|
unsigned GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
|
||||||
int FramePtrSpillFI = 0;
|
int FramePtrSpillFI = 0;
|
||||||
if (AFI->hasStackFrame()) {
|
if (!AFI->hasStackFrame()) {
|
||||||
if (VARegSaveSize)
|
if (NumBytes != 0)
|
||||||
emitSPUpdate(MBB, MBBI, -VARegSaveSize, isThumb, TII);
|
emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
if (VARegSaveSize)
|
||||||
unsigned Reg = CSI[i].getReg();
|
emitSPUpdate(MBB, MBBI, -VARegSaveSize, isThumb, TII);
|
||||||
int FI = CSI[i].getFrameIdx();
|
|
||||||
switch (Reg) {
|
for (unsigned i = 0, e = CSI.size(); i != e; ++i) {
|
||||||
case ARM::R4:
|
unsigned Reg = CSI[i].getReg();
|
||||||
case ARM::R5:
|
int FI = CSI[i].getFrameIdx();
|
||||||
case ARM::R6:
|
switch (Reg) {
|
||||||
case ARM::R7:
|
case ARM::R4:
|
||||||
case ARM::LR:
|
case ARM::R5:
|
||||||
if (Reg == FramePtr)
|
case ARM::R6:
|
||||||
FramePtrSpillFI = FI;
|
case ARM::R7:
|
||||||
|
case ARM::LR:
|
||||||
|
if (Reg == FramePtr)
|
||||||
|
FramePtrSpillFI = FI;
|
||||||
|
AFI->addGPRCalleeSavedArea1Frame(FI);
|
||||||
|
GPRCS1Size += 4;
|
||||||
|
break;
|
||||||
|
case ARM::R8:
|
||||||
|
case ARM::R9:
|
||||||
|
case ARM::R10:
|
||||||
|
case ARM::R11:
|
||||||
|
if (Reg == FramePtr)
|
||||||
|
FramePtrSpillFI = FI;
|
||||||
|
if (STI.isTargetDarwin()) {
|
||||||
|
AFI->addGPRCalleeSavedArea2Frame(FI);
|
||||||
|
GPRCS2Size += 4;
|
||||||
|
} else {
|
||||||
AFI->addGPRCalleeSavedArea1Frame(FI);
|
AFI->addGPRCalleeSavedArea1Frame(FI);
|
||||||
GPRCS1Size += 4;
|
GPRCS1Size += 4;
|
||||||
break;
|
|
||||||
case ARM::R8:
|
|
||||||
case ARM::R9:
|
|
||||||
case ARM::R10:
|
|
||||||
case ARM::R11:
|
|
||||||
if (Reg == FramePtr)
|
|
||||||
FramePtrSpillFI = FI;
|
|
||||||
if (STI.isTargetDarwin()) {
|
|
||||||
AFI->addGPRCalleeSavedArea2Frame(FI);
|
|
||||||
GPRCS2Size += 4;
|
|
||||||
} else {
|
|
||||||
AFI->addGPRCalleeSavedArea1Frame(FI);
|
|
||||||
GPRCS1Size += 4;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
AFI->addDPRCalleeSavedAreaFrame(FI);
|
|
||||||
DPRCSSize += 8;
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
if (Align == 8 && (GPRCS1Size & 7) != 0)
|
AFI->addDPRCalleeSavedAreaFrame(FI);
|
||||||
// Pad CS1 to ensure proper alignment.
|
DPRCSSize += 8;
|
||||||
GPRCS1Size += 4;
|
|
||||||
|
|
||||||
if (!isThumb) {
|
|
||||||
// Build the new SUBri to adjust SP for integer callee-save spill area 1.
|
|
||||||
emitSPUpdate(MBB, MBBI, -GPRCS1Size, isThumb, TII);
|
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
|
|
||||||
} else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH)
|
|
||||||
++MBBI;
|
|
||||||
|
|
||||||
// Point FP to the stack slot that contains the previous FP.
|
|
||||||
if (STI.isTargetDarwin())
|
|
||||||
BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri), FramePtr)
|
|
||||||
.addFrameIndex(FramePtrSpillFI).addImm(0);
|
|
||||||
|
|
||||||
if (!isThumb) {
|
|
||||||
// Build the new SUBri to adjust SP for integer callee-save spill area 2.
|
|
||||||
emitSPUpdate(MBB, MBBI, -GPRCS2Size, false, TII);
|
|
||||||
|
|
||||||
// Build the new SUBri to adjust SP for FP callee-save spill area.
|
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
|
|
||||||
emitSPUpdate(MBB, MBBI, -DPRCSSize, false, TII);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Align == 8 && (GPRCS1Size & 7) != 0)
|
||||||
|
// Pad CS1 to ensure proper alignment.
|
||||||
|
GPRCS1Size += 4;
|
||||||
|
|
||||||
|
if (!isThumb) {
|
||||||
|
// Build the new SUBri to adjust SP for integer callee-save spill area 1.
|
||||||
|
emitSPUpdate(MBB, MBBI, -GPRCS1Size, isThumb, TII);
|
||||||
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 1, STI);
|
||||||
|
} else if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH)
|
||||||
|
++MBBI;
|
||||||
|
|
||||||
|
// Point FP to the stack slot that contains the previous FP.
|
||||||
|
if (STI.isTargetDarwin())
|
||||||
|
BuildMI(MBB, MBBI, TII.get(isThumb ? ARM::tADDrSPi : ARM::ADDri), FramePtr)
|
||||||
|
.addFrameIndex(FramePtrSpillFI).addImm(0);
|
||||||
|
|
||||||
|
if (!isThumb) {
|
||||||
|
// Build the new SUBri to adjust SP for integer callee-save spill area 2.
|
||||||
|
emitSPUpdate(MBB, MBBI, -GPRCS2Size, false, TII);
|
||||||
|
|
||||||
|
// Build the new SUBri to adjust SP for FP callee-save spill area.
|
||||||
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::STR, 2, STI);
|
||||||
|
emitSPUpdate(MBB, MBBI, -DPRCSSize, false, TII);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine starting offsets of spill areas.
|
// Determine starting offsets of spill areas.
|
||||||
if (AFI->hasStackFrame()) {
|
unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
|
||||||
unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
|
unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
|
||||||
unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
|
unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
|
||||||
unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
|
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
|
||||||
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) + NumBytes);
|
AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
|
||||||
AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
|
AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
|
||||||
AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
|
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
|
||||||
AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
|
|
||||||
|
|
||||||
NumBytes = DPRCSOffset;
|
NumBytes = DPRCSOffset;
|
||||||
if (NumBytes) {
|
if (NumBytes) {
|
||||||
// Insert it after all the callee-save spills.
|
// Insert it after all the callee-save spills.
|
||||||
if (!isThumb)
|
if (!isThumb)
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::FSTD, 3, STI);
|
||||||
emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII);
|
emitSPUpdate(MBB, MBBI, -NumBytes, isThumb, TII);
|
||||||
|
}
|
||||||
|
|
||||||
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
||||||
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
||||||
@ -1005,58 +1012,60 @@ void ARMRegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
bool isThumb = AFI->isThumbFunction();
|
bool isThumb = AFI->isThumbFunction();
|
||||||
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
|
unsigned VARegSaveSize = AFI->getVarArgsRegSaveSize();
|
||||||
int NumBytes = (int)MFI->getStackSize();
|
int NumBytes = (int)MFI->getStackSize();
|
||||||
if (AFI->hasStackFrame()) {
|
if (!AFI->hasStackFrame()) {
|
||||||
// Unwind MBBI to point to first LDR / FLDD.
|
if (NumBytes != 0)
|
||||||
const unsigned *CSRegs = getCalleeSavedRegs();
|
|
||||||
if (MBBI != MBB.begin()) {
|
|
||||||
do
|
|
||||||
--MBBI;
|
|
||||||
while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
|
|
||||||
if (!isCSRestore(MBBI, CSRegs))
|
|
||||||
++MBBI;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move SP to start of FP callee save spill area.
|
|
||||||
NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
|
|
||||||
AFI->getGPRCalleeSavedArea2Size() +
|
|
||||||
AFI->getDPRCalleeSavedAreaSize());
|
|
||||||
if (isThumb)
|
|
||||||
emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
|
emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
|
||||||
else {
|
return;
|
||||||
if (STI.isTargetDarwin()) {
|
}
|
||||||
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
|
|
||||||
// Reset SP based on frame pointer only if the stack frame extends beyond
|
|
||||||
// frame pointer stack slot.
|
|
||||||
if (AFI->getGPRCalleeSavedArea2Size() ||
|
|
||||||
AFI->getDPRCalleeSavedAreaSize() ||
|
|
||||||
AFI->getDPRCalleeSavedAreaOffset())
|
|
||||||
if (NumBytes)
|
|
||||||
BuildMI(MBB, MBBI, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
|
|
||||||
.addImm(NumBytes);
|
|
||||||
else
|
|
||||||
BuildMI(MBB, MBBI, TII.get(ARM::MOVrr), ARM::SP).addReg(FramePtr);
|
|
||||||
} else if (NumBytes) {
|
|
||||||
emitSPUpdate(MBB, MBBI, NumBytes, false, TII);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move SP to start of integer callee save spill area 2.
|
// Unwind MBBI to point to first LDR / FLDD.
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
|
const unsigned *CSRegs = getCalleeSavedRegs();
|
||||||
emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), false, TII);
|
if (MBBI != MBB.begin()) {
|
||||||
|
do
|
||||||
|
--MBBI;
|
||||||
|
while (MBBI != MBB.begin() && isCSRestore(MBBI, CSRegs));
|
||||||
|
if (!isCSRestore(MBBI, CSRegs))
|
||||||
|
++MBBI;
|
||||||
|
}
|
||||||
|
|
||||||
// Move SP to start of integer callee save spill area 1.
|
// Move SP to start of FP callee save spill area.
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
|
NumBytes -= (AFI->getGPRCalleeSavedArea1Size() +
|
||||||
emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), false, TII);
|
AFI->getGPRCalleeSavedArea2Size() +
|
||||||
|
AFI->getDPRCalleeSavedAreaSize());
|
||||||
// Move SP to SP upon entry to the function.
|
if (isThumb)
|
||||||
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
|
emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
|
||||||
emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), false, TII);
|
else {
|
||||||
|
if (STI.isTargetDarwin()) {
|
||||||
|
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
|
||||||
|
// Reset SP based on frame pointer only if the stack frame extends beyond
|
||||||
|
// frame pointer stack slot.
|
||||||
|
if (AFI->getGPRCalleeSavedArea2Size() ||
|
||||||
|
AFI->getDPRCalleeSavedAreaSize() ||
|
||||||
|
AFI->getDPRCalleeSavedAreaOffset())
|
||||||
|
if (NumBytes)
|
||||||
|
BuildMI(MBB, MBBI, TII.get(ARM::SUBri), ARM::SP).addReg(FramePtr)
|
||||||
|
.addImm(NumBytes);
|
||||||
|
else
|
||||||
|
BuildMI(MBB, MBBI, TII.get(ARM::MOVrr), ARM::SP).addReg(FramePtr);
|
||||||
|
} else if (NumBytes) {
|
||||||
|
emitSPUpdate(MBB, MBBI, NumBytes, false, TII);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VARegSaveSize)
|
// Move SP to start of integer callee save spill area 2.
|
||||||
emitSPUpdate(MBB, MBBI, VARegSaveSize, isThumb, TII);
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::FLDD, 3, STI);
|
||||||
} else if (NumBytes != 0) {
|
emitSPUpdate(MBB, MBBI, AFI->getDPRCalleeSavedAreaSize(), false, TII);
|
||||||
emitSPUpdate(MBB, MBBI, NumBytes, isThumb, TII);
|
|
||||||
|
// Move SP to start of integer callee save spill area 1.
|
||||||
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 2, STI);
|
||||||
|
emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea2Size(), false, TII);
|
||||||
|
|
||||||
|
// Move SP to SP upon entry to the function.
|
||||||
|
movePastCSLoadStoreOps(MBB, MBBI, ARM::LDR, 1, STI);
|
||||||
|
emitSPUpdate(MBB, MBBI, AFI->getGPRCalleeSavedArea1Size(), false, TII);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (VARegSaveSize)
|
||||||
|
emitSPUpdate(MBB, MBBI, VARegSaveSize, isThumb, TII);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ARMRegisterInfo::getRARegister() const {
|
unsigned ARMRegisterInfo::getRARegister() const {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user