diff options
Diffstat (limited to 'llvm/lib/Target/ARM/ARMFrameLowering.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMFrameLowering.cpp | 123 |
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. |