summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMFrameLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/ARM/ARMFrameLowering.cpp')
-rw-r--r--llvm/lib/Target/ARM/ARMFrameLowering.cpp123
1 files changed, 97 insertions, 26 deletions
diff --git a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
index 1f2f6f7497e0..b9b417865691 100644
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
@@ -2488,6 +2488,7 @@ void ARMFrameLowering::adjustForSegmentedStacks(
unsigned CFIIndex;
const ARMSubtarget *ST = &MF.getSubtarget<ARMSubtarget>();
bool Thumb = ST->isThumb();
+ bool Thumb2 = ST->isThumb2();
// Sadly, this currently doesn't support varargs, platforms other than
// android/linux. Note that thumb1/thumb2 are support for android/linux.
@@ -2630,17 +2631,46 @@ void ARMFrameLowering::adjustForSegmentedStacks(
// sub SR1, sp, #StackSize
if (!CompareStackPointer && Thumb) {
- BuildMI(McrMBB, DL, TII.get(ARM::tSUBi8), ScratchReg1)
- .add(condCodeOp())
- .addReg(ScratchReg1)
- .addImm(AlignedStackSize)
- .add(predOps(ARMCC::AL));
+ if (AlignedStackSize < 256) {
+ BuildMI(McrMBB, DL, TII.get(ARM::tSUBi8), ScratchReg1)
+ .add(condCodeOp())
+ .addReg(ScratchReg1)
+ .addImm(AlignedStackSize)
+ .add(predOps(ARMCC::AL));
+ } else {
+ if (Thumb2) {
+ BuildMI(McrMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg0)
+ .addImm(AlignedStackSize);
+ } else {
+ auto MBBI = McrMBB->end();
+ auto RegInfo = STI.getRegisterInfo();
+ RegInfo->emitLoadConstPool(*McrMBB, MBBI, DL, ScratchReg0, 0,
+ AlignedStackSize);
+ }
+ BuildMI(McrMBB, DL, TII.get(ARM::tSUBrr), ScratchReg1)
+ .add(condCodeOp())
+ .addReg(ScratchReg1)
+ .addReg(ScratchReg0)
+ .add(predOps(ARMCC::AL));
+ }
} else if (!CompareStackPointer) {
- BuildMI(McrMBB, DL, TII.get(ARM::SUBri), ScratchReg1)
- .addReg(ARM::SP)
- .addImm(AlignedStackSize)
- .add(predOps(ARMCC::AL))
- .add(condCodeOp());
+ if (AlignedStackSize < 256) {
+ BuildMI(McrMBB, DL, TII.get(ARM::SUBri), ScratchReg1)
+ .addReg(ARM::SP)
+ .addImm(AlignedStackSize)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp());
+ } else {
+ auto MBBI = McrMBB->end();
+ auto RegInfo = STI.getRegisterInfo();
+ RegInfo->emitLoadConstPool(*McrMBB, MBBI, DL, ScratchReg0, 0,
+ AlignedStackSize);
+ BuildMI(McrMBB, DL, TII.get(ARM::SUBrr), ScratchReg1)
+ .addReg(ARM::SP)
+ .addReg(ScratchReg0)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp());
+ }
}
if (Thumb && ST->isThumb1Only()) {
@@ -2707,28 +2737,69 @@ void ARMFrameLowering::adjustForSegmentedStacks(
// Pass first argument for the __morestack by Scratch Register #0.
// The amount size of stack required
if (Thumb) {
- BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg0)
- .add(condCodeOp())
- .addImm(AlignedStackSize)
- .add(predOps(ARMCC::AL));
+ if (AlignedStackSize < 256) {
+ BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg0)
+ .add(condCodeOp())
+ .addImm(AlignedStackSize)
+ .add(predOps(ARMCC::AL));
+ } else {
+ if (Thumb2) {
+ BuildMI(AllocMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg0)
+ .addImm(AlignedStackSize);
+ } else {
+ auto MBBI = AllocMBB->end();
+ auto RegInfo = STI.getRegisterInfo();
+ RegInfo->emitLoadConstPool(*AllocMBB, MBBI, DL, ScratchReg0, 0,
+ AlignedStackSize);
+ }
+ }
} else {
- BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg0)
- .addImm(AlignedStackSize)
- .add(predOps(ARMCC::AL))
- .add(condCodeOp());
+ if (AlignedStackSize < 256) {
+ BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg0)
+ .addImm(AlignedStackSize)
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp());
+ } else {
+ auto MBBI = AllocMBB->end();
+ auto RegInfo = STI.getRegisterInfo();
+ RegInfo->emitLoadConstPool(*AllocMBB, MBBI, DL, ScratchReg0, 0,
+ AlignedStackSize);
+ }
}
+
// Pass second argument for the __morestack by Scratch Register #1.
// The amount size of stack consumed to save function arguments.
if (Thumb) {
- BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg1)
- .add(condCodeOp())
- .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
- .add(predOps(ARMCC::AL));
+ if (ARMFI->getArgumentStackSize() < 256) {
+ BuildMI(AllocMBB, DL, TII.get(ARM::tMOVi8), ScratchReg1)
+ .add(condCodeOp())
+ .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
+ .add(predOps(ARMCC::AL));
+ } else {
+ if (Thumb2) {
+ BuildMI(AllocMBB, DL, TII.get(ARM::t2MOVi32imm), ScratchReg1)
+ .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()));
+ } else {
+ auto MBBI = AllocMBB->end();
+ auto RegInfo = STI.getRegisterInfo();
+ RegInfo->emitLoadConstPool(
+ *AllocMBB, MBBI, DL, ScratchReg1, 0,
+ alignToARMConstant(ARMFI->getArgumentStackSize()));
+ }
+ }
} else {
- BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg1)
- .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
- .add(predOps(ARMCC::AL))
- .add(condCodeOp());
+ if (alignToARMConstant(ARMFI->getArgumentStackSize()) < 256) {
+ BuildMI(AllocMBB, DL, TII.get(ARM::MOVi), ScratchReg1)
+ .addImm(alignToARMConstant(ARMFI->getArgumentStackSize()))
+ .add(predOps(ARMCC::AL))
+ .add(condCodeOp());
+ } else {
+ auto MBBI = AllocMBB->end();
+ auto RegInfo = STI.getRegisterInfo();
+ RegInfo->emitLoadConstPool(
+ *AllocMBB, MBBI, DL, ScratchReg1, 0,
+ alignToARMConstant(ARMFI->getArgumentStackSize()));
+ }
}
// push {lr} - Save return address of this function.