174 lines · c
1//===-- M68kFrameLowering.h - Define frame lowering for M68k ----*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains the M68k declaration of TargetFrameLowering class.11///12//===----------------------------------------------------------------------===//13 14#ifndef LLVM_LIB_TARGET_M68K_M68KFRAMELOWERING_H15#define LLVM_LIB_TARGET_M68K_M68KFRAMELOWERING_H16 17#include "M68k.h"18 19#include "llvm/CodeGen/TargetFrameLowering.h"20 21namespace llvm {22class MachineInstrBuilder;23class MCCFIInstruction;24class M68kSubtarget;25class M68kRegisterInfo;26struct Align;27 28class M68kFrameLowering : public TargetFrameLowering {29 // Cached subtarget predicates.30 const M68kSubtarget &STI;31 const TargetInstrInfo &TII;32 const M68kRegisterInfo *TRI;33 34 /// Stack slot size in bytes.35 unsigned SlotSize;36 37 unsigned StackPtr;38 39 /// If we're forcing a stack realignment we can't rely on just the frame40 /// info, we need to know the ABI stack alignment as well in case we have a41 /// call out. Otherwise just make sure we have some alignment - we'll go42 /// with the minimum SlotSize.43 uint64_t calculateMaxStackAlign(const MachineFunction &MF) const;44 45 /// Adjusts the stack pointer using LEA, SUB, or ADD.46 MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB,47 MachineBasicBlock::iterator MBBI,48 const DebugLoc &DL, int64_t Offset,49 bool InEpilogue) const;50 51 /// Aligns the stack pointer by ANDing it with -MaxAlign.52 void BuildStackAlignAND(MachineBasicBlock &MBB,53 MachineBasicBlock::iterator MBBI, const DebugLoc &DL,54 unsigned Reg, uint64_t MaxAlign) const;55 56 /// Wraps up getting a CFI index and building a MachineInstr for it.57 void BuildCFI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,58 const DebugLoc &DL, const MCCFIInstruction &CFIInst) const;59 60 void emitPrologueCalleeSavedFrameMoves(MachineBasicBlock &MBB,61 MachineBasicBlock::iterator MBBI,62 const DebugLoc &DL) const;63 64 unsigned getPSPSlotOffsetFromSP(const MachineFunction &MF) const;65 66public:67 explicit M68kFrameLowering(const M68kSubtarget &sti, Align Alignment);68 69 static const M68kFrameLowering *create(const M68kSubtarget &ST);70 71 /// This method is called during prolog/epilog code insertion to eliminate72 /// call frame setup and destroy pseudo instructions (but only if the Target73 /// is using them). It is responsible for eliminating these instructions,74 /// replacing them with concrete instructions. This method need only be75 /// implemented if using call frame setup/destroy pseudo instructions.76 /// Returns an iterator pointing to the instruction after the replaced one.77 MachineBasicBlock::iterator78 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,79 MachineBasicBlock::iterator MI) const override;80 81 /// Insert prolog code into the function.82 void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;83 84 /// Insert epilog code into the function.85 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;86 87 /// This method determines which of the registers reported by88 /// TargetRegisterInfo::getCalleeSavedRegs() should actually get saved.89 /// The default implementation checks populates the \p SavedRegs bitset with90 /// all registers which are modified in the function, targets may override91 /// this function to save additional registers.92 /// This method also sets up the register scavenger ensuring there is a free93 /// register or a frameindex available.94 void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,95 RegScavenger *RS = nullptr) const override;96 97 /// Allows target to override spill slot assignment logic. If implemented,98 /// assignCalleeSavedSpillSlots() should assign frame slots to all CSI99 /// entries and return true. If this method returns false, spill slots will100 /// be assigned using generic implementation. assignCalleeSavedSpillSlots()101 /// may add, delete or rearrange elements of CSI.102 bool103 assignCalleeSavedSpillSlots(MachineFunction &MF,104 const TargetRegisterInfo *TRI,105 std::vector<CalleeSavedInfo> &CSI) const override;106 107 /// Issues instruction(s) to spill all callee saved registers and returns108 /// true if it isn't possible / profitable to do so by issuing a series of109 /// store instructions via storeRegToStackSlot(). Returns false otherwise.110 bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,111 MachineBasicBlock::iterator MI,112 ArrayRef<CalleeSavedInfo> CSI,113 const TargetRegisterInfo *TRI) const override;114 115 /// Issues instruction(s) to restore all callee saved registers and returns116 /// true if it isn't possible / profitable to do so by issuing a series of117 /// load instructions via loadRegToStackSlot(). Returns false otherwise.118 bool119 restoreCalleeSavedRegisters(MachineBasicBlock &MBB,120 MachineBasicBlock::iterator MI,121 MutableArrayRef<CalleeSavedInfo> CSI,122 const TargetRegisterInfo *TRI) const override;123 124 /// Under normal circumstances, when a frame pointer is not required, we125 /// reserve argument space for call sites in the function immediately on126 /// entry to the current function. This eliminates the need for add/sub sp127 /// brackets around call sites. Returns true if the call frame is included as128 /// part of the stack frame.129 bool hasReservedCallFrame(const MachineFunction &MF) const override;130 131 /// If there is a reserved call frame, the call frame pseudos can be132 /// simplified. Having a FP, as in the default implementation, is not133 /// sufficient here since we can't always use it. Use a more nuanced134 /// condition.135 bool canSimplifyCallFramePseudos(const MachineFunction &MF) const override;136 137 // Do we need to perform FI resolution for this function. Normally, this is138 // required only when the function has any stack objects. However, FI139 // resolution actually has another job, not apparent from the title - it140 // resolves callframe setup/destroy that were not simplified earlier.141 //142 // So, this is required for M68k functions that have push sequences even143 // when there are no stack objects.144 bool needsFrameIndexResolution(const MachineFunction &MF) const override;145 146 /// This method should return the base register and offset used to reference147 /// a frame index location. The offset is returned directly, and the base148 /// register is returned via FrameReg.149 StackOffset getFrameIndexReference(const MachineFunction &MF, int FI,150 Register &FrameReg) const override;151 152 /// Check the instruction before/after the passed instruction. If153 /// it is an ADD/SUB/LEA instruction it is deleted argument and the154 /// stack adjustment is returned as a positive value for ADD/LEA and155 /// a negative for SUB.156 int mergeSPUpdates(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,157 bool doMergeWithPrevious) const;158 159 /// Emit a series of instructions to increment / decrement the stack160 /// pointer by a constant value.161 void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,162 int64_t NumBytes, bool InEpilogue) const;163 164protected:165 /// Return true if the specified function should have a dedicated frame166 /// pointer register. This is true if the function has variable sized167 /// allocas, if it needs dynamic stack realignment, if frame pointer168 /// elimination is disabled, or if the frame address is taken.169 bool hasFPImpl(const MachineFunction &MF) const override;170};171} // namespace llvm172 173#endif // LLVM_LIB_TARGET_M68K_M68KFRAMELOWERING_H174