1*0b57cec5SDimitry Andric //===- Thumb1FrameLowering.h - Thumb1-specific frame info stuff ---*- C++ -*-=// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_ARM_THUMB1FRAMELOWERING_H 10*0b57cec5SDimitry Andric #define LLVM_LIB_TARGET_ARM_THUMB1FRAMELOWERING_H 11*0b57cec5SDimitry Andric 12*0b57cec5SDimitry Andric #include "ARMFrameLowering.h" 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric namespace llvm { 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric class ARMSubtarget; 17*0b57cec5SDimitry Andric class MachineFunction; 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric class Thumb1FrameLowering : public ARMFrameLowering { 20*0b57cec5SDimitry Andric public: 21*0b57cec5SDimitry Andric explicit Thumb1FrameLowering(const ARMSubtarget &sti); 22*0b57cec5SDimitry Andric 23*0b57cec5SDimitry Andric /// emitProlog/emitEpilog - These methods insert prolog and epilog code into 24*0b57cec5SDimitry Andric /// the function. 25*0b57cec5SDimitry Andric void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 26*0b57cec5SDimitry Andric void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override; 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, 29*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI, 30*0b57cec5SDimitry Andric const std::vector<CalleeSavedInfo> &CSI, 31*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 32*0b57cec5SDimitry Andric bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, 33*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI, 34*0b57cec5SDimitry Andric std::vector<CalleeSavedInfo> &CSI, 35*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 36*0b57cec5SDimitry Andric 37*0b57cec5SDimitry Andric bool hasReservedCallFrame(const MachineFunction &MF) const override; 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric MachineBasicBlock::iterator 40*0b57cec5SDimitry Andric eliminateCallFramePseudoInstr(MachineFunction &MF, 41*0b57cec5SDimitry Andric MachineBasicBlock &MBB, 42*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI) const override; 43*0b57cec5SDimitry Andric 44*0b57cec5SDimitry Andric /// Check whether or not the given \p MBB can be used as a epilogue 45*0b57cec5SDimitry Andric /// for the target. 46*0b57cec5SDimitry Andric /// The epilogue will be inserted before the first terminator of that block. 47*0b57cec5SDimitry Andric /// This method is used by the shrink-wrapping pass to decide if 48*0b57cec5SDimitry Andric /// \p MBB will be correctly handled by the target. 49*0b57cec5SDimitry Andric bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override; 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric /// Disable shrink wrap as tBfar/BL will be used to adjust for long jumps. 52*0b57cec5SDimitry Andric bool enableShrinkWrapping(const MachineFunction &MF) const override { 53*0b57cec5SDimitry Andric return false; 54*0b57cec5SDimitry Andric } 55*0b57cec5SDimitry Andric 56*0b57cec5SDimitry Andric private: 57*0b57cec5SDimitry Andric /// Check if the frame lowering of \p MF needs a special fixup 58*0b57cec5SDimitry Andric /// code sequence for the epilogue. 59*0b57cec5SDimitry Andric /// Unlike T2 and ARM mode, the T1 pop instruction cannot restore 60*0b57cec5SDimitry Andric /// to LR, and we can't pop the value directly to the PC when 61*0b57cec5SDimitry Andric /// we need to update the SP after popping the value. So instead 62*0b57cec5SDimitry Andric /// we have to emit: 63*0b57cec5SDimitry Andric /// POP {r3} 64*0b57cec5SDimitry Andric /// ADD sp, #offset 65*0b57cec5SDimitry Andric /// BX r3 66*0b57cec5SDimitry Andric /// If this would clobber a return value, then generate this sequence instead: 67*0b57cec5SDimitry Andric /// MOV ip, r3 68*0b57cec5SDimitry Andric /// POP {r3} 69*0b57cec5SDimitry Andric /// ADD sp, #offset 70*0b57cec5SDimitry Andric /// MOV lr, r3 71*0b57cec5SDimitry Andric /// MOV r3, ip 72*0b57cec5SDimitry Andric /// BX lr 73*0b57cec5SDimitry Andric bool needPopSpecialFixUp(const MachineFunction &MF) const; 74*0b57cec5SDimitry Andric 75*0b57cec5SDimitry Andric /// Emit the special fixup code sequence for the epilogue. 76*0b57cec5SDimitry Andric /// \see needPopSpecialFixUp for more details. 77*0b57cec5SDimitry Andric /// \p DoIt, tells this method whether or not to actually insert 78*0b57cec5SDimitry Andric /// the code sequence in \p MBB. I.e., when \p DoIt is false, 79*0b57cec5SDimitry Andric /// \p MBB is left untouched. 80*0b57cec5SDimitry Andric /// \returns For \p DoIt == true: True when the emission succeeded 81*0b57cec5SDimitry Andric /// false otherwise. For \p DoIt == false: True when the emission 82*0b57cec5SDimitry Andric /// would have been possible, false otherwise. 83*0b57cec5SDimitry Andric bool emitPopSpecialFixUp(MachineBasicBlock &MBB, bool DoIt) const; 84*0b57cec5SDimitry Andric }; 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric } // end namespace llvm 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_ARM_THUMB1FRAMELOWERING_H 89