mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Revert r110655, "Fix ARM hasFP() semantics. It should return true whenever FP
register is", it breaks a couple test-suite tests. llvm-svn: 110701
This commit is contained in:
parent
f7233103ff
commit
872e84afb5
@ -177,7 +177,7 @@ getReservedRegs(const MachineFunction &MF) const {
|
|||||||
Reserved.set(ARM::SP);
|
Reserved.set(ARM::SP);
|
||||||
Reserved.set(ARM::PC);
|
Reserved.set(ARM::PC);
|
||||||
Reserved.set(ARM::FPSCR);
|
Reserved.set(ARM::FPSCR);
|
||||||
if (hasFP(MF))
|
if (STI.isTargetDarwin() || hasFP(MF))
|
||||||
Reserved.set(FramePtr);
|
Reserved.set(FramePtr);
|
||||||
// Some targets reserve R9.
|
// Some targets reserve R9.
|
||||||
if (STI.isR9Reserved())
|
if (STI.isR9Reserved())
|
||||||
@ -194,7 +194,7 @@ bool ARMBaseRegisterInfo::isReservedReg(const MachineFunction &MF,
|
|||||||
return true;
|
return true;
|
||||||
case ARM::R7:
|
case ARM::R7:
|
||||||
case ARM::R11:
|
case ARM::R11:
|
||||||
if (FramePtr == Reg && hasFP(MF))
|
if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case ARM::R9:
|
case ARM::R9:
|
||||||
@ -511,7 +511,7 @@ ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
|
|||||||
return std::make_pair(RC->allocation_order_begin(MF),
|
return std::make_pair(RC->allocation_order_begin(MF),
|
||||||
RC->allocation_order_end(MF));
|
RC->allocation_order_end(MF));
|
||||||
|
|
||||||
if (!hasFP(MF)) {
|
if (!STI.isTargetDarwin() && !hasFP(MF)) {
|
||||||
if (!STI.isR9Reserved())
|
if (!STI.isR9Reserved())
|
||||||
return std::make_pair(GPREven1,
|
return std::make_pair(GPREven1,
|
||||||
GPREven1 + (sizeof(GPREven1)/sizeof(unsigned)));
|
GPREven1 + (sizeof(GPREven1)/sizeof(unsigned)));
|
||||||
@ -540,7 +540,7 @@ ARMBaseRegisterInfo::getAllocationOrder(const TargetRegisterClass *RC,
|
|||||||
return std::make_pair(RC->allocation_order_begin(MF),
|
return std::make_pair(RC->allocation_order_begin(MF),
|
||||||
RC->allocation_order_end(MF));
|
RC->allocation_order_end(MF));
|
||||||
|
|
||||||
if (!hasFP(MF)) {
|
if (!STI.isTargetDarwin() && !hasFP(MF)) {
|
||||||
if (!STI.isR9Reserved())
|
if (!STI.isR9Reserved())
|
||||||
return std::make_pair(GPROdd1,
|
return std::make_pair(GPROdd1,
|
||||||
GPROdd1 + (sizeof(GPROdd1)/sizeof(unsigned)));
|
GPROdd1 + (sizeof(GPROdd1)/sizeof(unsigned)));
|
||||||
@ -610,10 +610,6 @@ ARMBaseRegisterInfo::UpdateRegAllocHint(unsigned Reg, unsigned NewReg,
|
|||||||
/// or if frame pointer elimination is disabled.
|
/// or if frame pointer elimination is disabled.
|
||||||
///
|
///
|
||||||
bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
|
bool ARMBaseRegisterInfo::hasFP(const MachineFunction &MF) const {
|
||||||
// Mac OS X requires FP not to be clobbered for backtracing purpose.
|
|
||||||
if (STI.isTargetDarwin())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
// Always eliminate non-leaf frame pointers.
|
// Always eliminate non-leaf frame pointers.
|
||||||
return ((DisableFramePointerElim(MF) && MFI->hasCalls()) ||
|
return ((DisableFramePointerElim(MF) && MFI->hasCalls()) ||
|
||||||
@ -687,7 +683,6 @@ static unsigned estimateStackSize(MachineFunction &MF) {
|
|||||||
/// instructions will require a scratch register during their expansion later.
|
/// instructions will require a scratch register during their expansion later.
|
||||||
unsigned
|
unsigned
|
||||||
ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
|
ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
|
||||||
const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
|
|
||||||
unsigned Limit = (1 << 12) - 1;
|
unsigned Limit = (1 << 12) - 1;
|
||||||
for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
|
for (MachineFunction::iterator BB = MF.begin(),E = MF.end(); BB != E; ++BB) {
|
||||||
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
|
for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
|
||||||
@ -713,10 +708,7 @@ ARMBaseRegisterInfo::estimateRSStackSizeLimit(MachineFunction &MF) const {
|
|||||||
Limit = std::min(Limit, ((1U << 8) - 1) * 4);
|
Limit = std::min(Limit, ((1U << 8) - 1) * 4);
|
||||||
break;
|
break;
|
||||||
case ARMII::AddrModeT2_i12:
|
case ARMII::AddrModeT2_i12:
|
||||||
// i12 supports only positive offset so these will be converted to
|
if (hasFP(MF)) Limit = std::min(Limit, (1U << 8) - 1);
|
||||||
// i8 opcodes. See llvm::rewriteT2FrameIndex.
|
|
||||||
if (hasFP(MF) && AFI->hasStackFrame())
|
|
||||||
Limit = std::min(Limit, (1U << 8) - 1);
|
|
||||||
break;
|
break;
|
||||||
case ARMII::AddrMode6:
|
case ARMII::AddrMode6:
|
||||||
// Addressing mode 6 (load/store) instructions can't encode an
|
// Addressing mode 6 (load/store) instructions can't encode an
|
||||||
@ -868,9 +860,8 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
// and which instructions will need a scratch register for them. Is it
|
// and which instructions will need a scratch register for them. Is it
|
||||||
// worth the effort and added fragility?
|
// worth the effort and added fragility?
|
||||||
bool BigStack =
|
bool BigStack =
|
||||||
(RS &&
|
(RS && (estimateStackSize(MF) + (hasFP(MF) ? 4:0) >=
|
||||||
(estimateStackSize(MF) + ((hasFP(MF) && AFI->hasStackFrame()) ? 4:0) >=
|
estimateRSStackSizeLimit(MF)))
|
||||||
estimateRSStackSizeLimit(MF)))
|
|
||||||
|| MFI->hasVarSizedObjects()
|
|| MFI->hasVarSizedObjects()
|
||||||
|| (MFI->adjustsStack() && !canSimplifyCallFramePseudos(MF));
|
|| (MFI->adjustsStack() && !canSimplifyCallFramePseudos(MF));
|
||||||
|
|
||||||
@ -890,7 +881,9 @@ ARMBaseRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
|
|||||||
ExtraCSSpill = true;
|
ExtraCSSpill = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFP(MF)) {
|
// Darwin ABI requires FP to point to the stack slot that contains the
|
||||||
|
// previous FP.
|
||||||
|
if (STI.isTargetDarwin() || hasFP(MF)) {
|
||||||
MF.getRegInfo().setPhysRegUsed(FramePtr);
|
MF.getRegInfo().setPhysRegUsed(FramePtr);
|
||||||
NumGPRSpills++;
|
NumGPRSpills++;
|
||||||
}
|
}
|
||||||
@ -983,7 +976,7 @@ unsigned ARMBaseRegisterInfo::getRARegister() const {
|
|||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
ARMBaseRegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
||||||
if (hasFP(MF))
|
if (STI.isTargetDarwin() || hasFP(MF))
|
||||||
return FramePtr;
|
return FramePtr;
|
||||||
return ARM::SP;
|
return ARM::SP;
|
||||||
}
|
}
|
||||||
@ -1553,8 +1546,7 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
// Otherwise, if this is not Darwin, all the callee-saved registers go
|
// Otherwise, if this is not Darwin, all the callee-saved registers go
|
||||||
// into spill area 1, including the FP in R11. In either case, it is
|
// into spill area 1, including the FP in R11. In either case, it is
|
||||||
// now safe to emit this assignment.
|
// now safe to emit this assignment.
|
||||||
bool HasFP = hasFP(MF);
|
if (STI.isTargetDarwin() || hasFP(MF)) {
|
||||||
if (HasFP) {
|
|
||||||
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
|
unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
|
||||||
MachineInstrBuilder MIB =
|
MachineInstrBuilder MIB =
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(ADDriOpc), FramePtr)
|
BuildMI(MBB, MBBI, dl, TII.get(ADDriOpc), FramePtr)
|
||||||
@ -1573,7 +1565,7 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
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;
|
||||||
if (HasFP)
|
if (STI.isTargetDarwin() || hasFP(MF))
|
||||||
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
|
AFI->setFramePtrSpillOffset(MFI->getObjectOffset(FramePtrSpillFI) +
|
||||||
NumBytes);
|
NumBytes);
|
||||||
AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
|
AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
|
||||||
@ -1585,14 +1577,11 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
if (NumBytes) {
|
if (NumBytes) {
|
||||||
// Adjust SP after all the callee-save spills.
|
// Adjust SP after all the callee-save spills.
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, -NumBytes);
|
||||||
if (HasFP)
|
|
||||||
AFI->setShouldRestoreSPFromFP(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STI.isTargetELF() && hasFP(MF)) {
|
if (STI.isTargetELF() && hasFP(MF)) {
|
||||||
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
|
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
|
||||||
AFI->getFramePtrSpillOffset());
|
AFI->getFramePtrSpillOffset());
|
||||||
AFI->setShouldRestoreSPFromFP(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
||||||
@ -1625,8 +1614,6 @@ emitPrologue(MachineFunction &MF) const {
|
|||||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
|
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVtgpr2gpr), ARM::SP)
|
||||||
.addReg(ARM::R4, RegState::Kill);
|
.addReg(ARM::R4, RegState::Kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
AFI->setShouldRestoreSPFromFP(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1682,25 +1669,34 @@ emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const {
|
|||||||
AFI->getGPRCalleeSavedArea2Size() +
|
AFI->getGPRCalleeSavedArea2Size() +
|
||||||
AFI->getDPRCalleeSavedAreaSize());
|
AFI->getDPRCalleeSavedAreaSize());
|
||||||
|
|
||||||
// Reset SP based on frame pointer only if the stack frame extends beyond
|
// Darwin ABI requires FP to point to the stack slot that contains the
|
||||||
// frame pointer stack slot or target is ELF and the function has FP.
|
// previous FP.
|
||||||
if (AFI->shouldRestoreSPFromFP()) {
|
bool HasFP = hasFP(MF);
|
||||||
|
if ((STI.isTargetDarwin() && NumBytes) || HasFP) {
|
||||||
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
|
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
|
||||||
if (NumBytes) {
|
// Reset SP based on frame pointer only if the stack frame extends beyond
|
||||||
if (isARM)
|
// frame pointer stack slot or target is ELF and the function has FP.
|
||||||
emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
|
if (HasFP ||
|
||||||
ARMCC::AL, 0, TII);
|
AFI->getGPRCalleeSavedArea2Size() ||
|
||||||
else
|
AFI->getDPRCalleeSavedAreaSize() ||
|
||||||
emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
|
AFI->getDPRCalleeSavedAreaOffset()) {
|
||||||
ARMCC::AL, 0, TII);
|
if (NumBytes) {
|
||||||
} else {
|
if (isARM)
|
||||||
// Thumb2 or ARM.
|
emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
|
||||||
if (isARM)
|
ARMCC::AL, 0, TII);
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
|
else
|
||||||
.addReg(FramePtr).addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
|
emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, FramePtr, -NumBytes,
|
||||||
else
|
ARMCC::AL, 0, TII);
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP)
|
} else {
|
||||||
.addReg(FramePtr);
|
// Thumb2 or ARM.
|
||||||
|
if (isARM)
|
||||||
|
BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), ARM::SP)
|
||||||
|
.addReg(FramePtr)
|
||||||
|
.addImm((unsigned)ARMCC::AL).addReg(0).addReg(0);
|
||||||
|
else
|
||||||
|
BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVgpr2gpr), ARM::SP)
|
||||||
|
.addReg(FramePtr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (NumBytes)
|
} else if (NumBytes)
|
||||||
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
emitSPUpdate(isARM, MBB, MBBI, dl, TII, NumBytes);
|
||||||
|
@ -742,15 +742,14 @@ Sched::Preference ARMTargetLowering::getSchedulingPreference(SDNode *N) const {
|
|||||||
unsigned
|
unsigned
|
||||||
ARMTargetLowering::getRegPressureLimit(const TargetRegisterClass *RC,
|
ARMTargetLowering::getRegPressureLimit(const TargetRegisterClass *RC,
|
||||||
MachineFunction &MF) const {
|
MachineFunction &MF) const {
|
||||||
|
unsigned FPDiff = RegInfo->hasFP(MF) ? 1 : 0;
|
||||||
switch (RC->getID()) {
|
switch (RC->getID()) {
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
case ARM::tGPRRegClassID:
|
case ARM::tGPRRegClassID:
|
||||||
return RegInfo->hasFP(MF) ? 4 : 5;
|
return 5 - FPDiff;
|
||||||
case ARM::GPRRegClassID: {
|
case ARM::GPRRegClassID:
|
||||||
unsigned FP = RegInfo->hasFP(MF) ? 1 : 0;
|
return 10 - FPDiff - (Subtarget->isR9Reserved() ? 1 : 0);
|
||||||
return 10 - FP - (Subtarget->isR9Reserved() ? 1 : 0);
|
|
||||||
}
|
|
||||||
case ARM::SPRRegClassID: // Currently not used as 'rep' register class.
|
case ARM::SPRRegClassID: // Currently not used as 'rep' register class.
|
||||||
case ARM::DPRRegClassID:
|
case ARM::DPRRegClassID:
|
||||||
return 32 - 10;
|
return 32 - 10;
|
||||||
|
@ -43,10 +43,6 @@ class ARMFunctionInfo : public MachineFunctionInfo {
|
|||||||
/// processFunctionBeforeCalleeSavedScan().
|
/// processFunctionBeforeCalleeSavedScan().
|
||||||
bool HasStackFrame;
|
bool HasStackFrame;
|
||||||
|
|
||||||
/// RestoreSPFromFP - True if epilogue should restore SP from FP. Set by
|
|
||||||
/// emitPrologue.
|
|
||||||
bool RestoreSPFromFP;
|
|
||||||
|
|
||||||
/// LRSpilledForFarJump - True if the LR register has been for spilled to
|
/// LRSpilledForFarJump - True if the LR register has been for spilled to
|
||||||
/// enable far jump.
|
/// enable far jump.
|
||||||
bool LRSpilledForFarJump;
|
bool LRSpilledForFarJump;
|
||||||
@ -99,7 +95,7 @@ public:
|
|||||||
ARMFunctionInfo() :
|
ARMFunctionInfo() :
|
||||||
isThumb(false),
|
isThumb(false),
|
||||||
hasThumb2(false),
|
hasThumb2(false),
|
||||||
VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
|
VarArgsRegSaveSize(0), HasStackFrame(false),
|
||||||
LRSpilledForFarJump(false),
|
LRSpilledForFarJump(false),
|
||||||
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
||||||
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
|
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
|
||||||
@ -110,7 +106,7 @@ public:
|
|||||||
explicit ARMFunctionInfo(MachineFunction &MF) :
|
explicit ARMFunctionInfo(MachineFunction &MF) :
|
||||||
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
|
isThumb(MF.getTarget().getSubtarget<ARMSubtarget>().isThumb()),
|
||||||
hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
|
hasThumb2(MF.getTarget().getSubtarget<ARMSubtarget>().hasThumb2()),
|
||||||
VarArgsRegSaveSize(0), HasStackFrame(false), RestoreSPFromFP(false),
|
VarArgsRegSaveSize(0), HasStackFrame(false),
|
||||||
LRSpilledForFarJump(false),
|
LRSpilledForFarJump(false),
|
||||||
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
|
||||||
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
|
GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
|
||||||
@ -129,9 +125,6 @@ public:
|
|||||||
bool hasStackFrame() const { return HasStackFrame; }
|
bool hasStackFrame() const { return HasStackFrame; }
|
||||||
void setHasStackFrame(bool s) { HasStackFrame = s; }
|
void setHasStackFrame(bool s) { HasStackFrame = s; }
|
||||||
|
|
||||||
bool shouldRestoreSPFromFP() const { return RestoreSPFromFP; }
|
|
||||||
void setShouldRestoreSPFromFP(bool s) { RestoreSPFromFP = s; }
|
|
||||||
|
|
||||||
bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
|
bool isLRSpilledForFarJump() const { return LRSpilledForFarJump; }
|
||||||
void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
|
void setLRIsSpilledForFarJump(bool s) { LRSpilledForFarJump = s; }
|
||||||
|
|
||||||
|
@ -294,7 +294,8 @@ def GPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
|
|||||||
|
|
||||||
if (Subtarget.isThumb1Only()) {
|
if (Subtarget.isThumb1Only()) {
|
||||||
I = THUMB_GPR_AO + (sizeof(THUMB_GPR_AO)/sizeof(unsigned));
|
I = THUMB_GPR_AO + (sizeof(THUMB_GPR_AO)/sizeof(unsigned));
|
||||||
return RI->hasFP(MF) ? I-1 : I;
|
// Mac OS X requires FP not to be clobbered for backtracing purpose.
|
||||||
|
return (Subtarget.isTargetDarwin() || RI->hasFP(MF)) ? I-1 : I;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Subtarget.isTargetDarwin()) {
|
if (Subtarget.isTargetDarwin()) {
|
||||||
@ -311,7 +312,8 @@ def GPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
|
|||||||
I = ARM_GPR_AO_1 + (sizeof(ARM_GPR_AO_1)/sizeof(unsigned));
|
I = ARM_GPR_AO_1 + (sizeof(ARM_GPR_AO_1)/sizeof(unsigned));
|
||||||
}
|
}
|
||||||
|
|
||||||
return RI->hasFP(MF) ? I-1 : I;
|
// Mac OS X requires FP not to be clobbered for backtracing purpose.
|
||||||
|
return (Subtarget.isTargetDarwin() || RI->hasFP(MF)) ? I-1 : I;
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@ -401,7 +403,8 @@ def rGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
|
|||||||
|
|
||||||
if (Subtarget.isThumb1Only()) {
|
if (Subtarget.isThumb1Only()) {
|
||||||
I = THUMB_rGPRAO + (sizeof(THUMB_rGPRAO)/sizeof(unsigned));
|
I = THUMB_rGPRAO + (sizeof(THUMB_rGPRAO)/sizeof(unsigned));
|
||||||
return RI->hasFP(MF) ? I-1 : I;
|
// Mac OS X requires FP not to be clobbered for backtracing purpose.
|
||||||
|
return (Subtarget.isTargetDarwin() || RI->hasFP(MF)) ? I-1 : I;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Subtarget.isTargetDarwin()) {
|
if (Subtarget.isTargetDarwin()) {
|
||||||
@ -418,7 +421,8 @@ def rGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6,
|
|||||||
I = ARM_rGPRAO_1 + (sizeof(ARM_rGPRAO_1)/sizeof(unsigned));
|
I = ARM_rGPRAO_1 + (sizeof(ARM_rGPRAO_1)/sizeof(unsigned));
|
||||||
}
|
}
|
||||||
|
|
||||||
return RI->hasFP(MF) ? I-1 : I;
|
// Mac OS X requires FP not to be clobbered for backtracing purpose.
|
||||||
|
return (Subtarget.isTargetDarwin() || RI->hasFP(MF)) ? I-1 : I;
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
@ -445,9 +449,11 @@ def tGPR : RegisterClass<"ARM", [i32], 32, [R0, R1, R2, R3, R4, R5, R6, R7]> {
|
|||||||
tGPRClass::allocation_order_end(const MachineFunction &MF) const {
|
tGPRClass::allocation_order_end(const MachineFunction &MF) const {
|
||||||
const TargetMachine &TM = MF.getTarget();
|
const TargetMachine &TM = MF.getTarget();
|
||||||
const TargetRegisterInfo *RI = TM.getRegisterInfo();
|
const TargetRegisterInfo *RI = TM.getRegisterInfo();
|
||||||
|
const ARMSubtarget &Subtarget = TM.getSubtarget<ARMSubtarget>();
|
||||||
tGPRClass::iterator I =
|
tGPRClass::iterator I =
|
||||||
THUMB_tGPR_AO + (sizeof(THUMB_tGPR_AO)/sizeof(unsigned));
|
THUMB_tGPR_AO + (sizeof(THUMB_tGPR_AO)/sizeof(unsigned));
|
||||||
return RI->hasFP(MF) ? I-1 : I;
|
// Mac OS X requires FP not to be clobbered for backtracing purpose.
|
||||||
|
return (Subtarget.isTargetDarwin() || RI->hasFP(MF)) ? I-1 : I;
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
@ -742,11 +742,11 @@ void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
dl = MBBI->getDebugLoc();
|
dl = MBBI->getDebugLoc();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adjust FP so it point to the stack slot that contains the previous FP.
|
// Darwin ABI requires FP to point to the stack slot that contains the
|
||||||
if (hasFP(MF)) {
|
// previous FP.
|
||||||
|
if (STI.isTargetDarwin() || hasFP(MF)) {
|
||||||
BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
|
BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
|
||||||
.addFrameIndex(FramePtrSpillFI).addImm(0);
|
.addFrameIndex(FramePtrSpillFI).addImm(0);
|
||||||
AFI->setShouldRestoreSPFromFP(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine starting offsets of spill areas.
|
// Determine starting offsets of spill areas.
|
||||||
@ -764,9 +764,10 @@ void Thumb1RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
|
emitSPUpdate(MBB, MBBI, TII, dl, *this, -NumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (STI.isTargetELF() && hasFP(MF))
|
if (STI.isTargetELF() && hasFP(MF)) {
|
||||||
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
|
MFI->setOffsetAdjustment(MFI->getOffsetAdjustment() -
|
||||||
AFI->getFramePtrSpillOffset());
|
AFI->getFramePtrSpillOffset());
|
||||||
|
}
|
||||||
|
|
||||||
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
AFI->setGPRCalleeSavedArea1Size(GPRCS1Size);
|
||||||
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
AFI->setGPRCalleeSavedArea2Size(GPRCS2Size);
|
||||||
@ -827,7 +828,7 @@ void Thumb1RegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
AFI->getGPRCalleeSavedArea2Size() +
|
AFI->getGPRCalleeSavedArea2Size() +
|
||||||
AFI->getDPRCalleeSavedAreaSize());
|
AFI->getDPRCalleeSavedAreaSize());
|
||||||
|
|
||||||
if (AFI->shouldRestoreSPFromFP()) {
|
if (hasFP(MF)) {
|
||||||
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
|
NumBytes = AFI->getFramePtrSpillOffset() - NumBytes;
|
||||||
// Reset SP based on frame pointer only if the stack frame extends beyond
|
// Reset SP based on frame pointer only if the stack frame extends beyond
|
||||||
// frame pointer stack slot or target is ELF and the function has FP.
|
// frame pointer stack slot or target is ELF and the function has FP.
|
||||||
|
@ -1,35 +1,20 @@
|
|||||||
; RUN: llc < %s -mtriple=thumb-apple-darwin | FileCheck %s
|
; RUN: llc < %s -march=thumb | grep {ldr.*LCP} | count 5
|
||||||
|
|
||||||
define void @test1() {
|
define void @test1() {
|
||||||
; CHECK: test1:
|
|
||||||
; CHECK: sub sp, #256
|
|
||||||
; CHECK: add sp, #256
|
|
||||||
%tmp = alloca [ 64 x i32 ] , align 4
|
%tmp = alloca [ 64 x i32 ] , align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define void @test2() {
|
define void @test2() {
|
||||||
; CHECK: test2:
|
|
||||||
; CHECK: ldr r0, LCPI
|
|
||||||
; CHECK: add sp, r0
|
|
||||||
; CHECK: mov sp, r7
|
|
||||||
; CHECK: sub sp, #4
|
|
||||||
%tmp = alloca [ 4168 x i8 ] , align 4
|
%tmp = alloca [ 4168 x i8 ] , align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
define i32 @test3() {
|
define i32 @test3() {
|
||||||
; CHECK: test3:
|
%retval = alloca i32, align 4
|
||||||
; CHECK: ldr r1, LCPI
|
%tmp = alloca i32, align 4
|
||||||
; CHECK: add sp, r1
|
%a = alloca [805306369 x i8], align 16
|
||||||
; CHECK: ldr r1, LCPI
|
store i32 0, i32* %tmp
|
||||||
; CHECK: add r1, sp
|
%tmp1 = load i32* %tmp
|
||||||
; CHECK: mov sp, r7
|
ret i32 %tmp1
|
||||||
; CHECK: sub sp, #4
|
|
||||||
%retval = alloca i32, align 4
|
|
||||||
%tmp = alloca i32, align 4
|
|
||||||
%a = alloca [805306369 x i8], align 16
|
|
||||||
store i32 0, i32* %tmp
|
|
||||||
%tmp1 = load i32* %tmp
|
|
||||||
ret i32 %tmp1
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user