1//==-- AArch64FrameLowering.h - TargetFrameLowering for AArch64 --*- 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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
14#define LLVM_LIB_TARGET_AARCH64_AARCH64FRAMELOWERING_H
15
16#include "AArch64StackOffset.h"
17#include "llvm/CodeGen/TargetFrameLowering.h"
18
19namespace llvm {
20
21class AArch64FrameLowering : public TargetFrameLowering {
22public:
23  explicit AArch64FrameLowering()
24      : TargetFrameLowering(StackGrowsDown, Align(16), 0, Align(16),
25                            true /*StackRealignable*/) {}
26
27  void emitCalleeSavedFrameMoves(MachineBasicBlock &MBB,
28                                 MachineBasicBlock::iterator MBBI) const;
29
30  MachineBasicBlock::iterator
31  eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
32                                MachineBasicBlock::iterator I) const override;
33
34  /// emitProlog/emitEpilog - These methods insert prolog and epilog code into
35  /// the function.
36  void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
37  void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override;
38
39  bool canUseAsPrologue(const MachineBasicBlock &MBB) const override;
40
41  int getFrameIndexReference(const MachineFunction &MF, int FI,
42                             unsigned &FrameReg) const override;
43  StackOffset resolveFrameIndexReference(const MachineFunction &MF, int FI,
44                                         unsigned &FrameReg, bool PreferFP,
45                                         bool ForSimm) const;
46  StackOffset resolveFrameOffsetReference(const MachineFunction &MF,
47                                          int64_t ObjectOffset, bool isFixed,
48                                          bool isSVE, unsigned &FrameReg,
49                                          bool PreferFP, bool ForSimm) const;
50  bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
51                                 MachineBasicBlock::iterator MI,
52                                 const std::vector<CalleeSavedInfo> &CSI,
53                                 const TargetRegisterInfo *TRI) const override;
54
55  bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
56                                  MachineBasicBlock::iterator MI,
57                                  std::vector<CalleeSavedInfo> &CSI,
58                                  const TargetRegisterInfo *TRI) const override;
59
60  /// Can this function use the red zone for local allocations.
61  bool canUseRedZone(const MachineFunction &MF) const;
62
63  bool hasFP(const MachineFunction &MF) const override;
64  bool hasReservedCallFrame(const MachineFunction &MF) const override;
65
66  void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
67                            RegScavenger *RS) const override;
68
69  /// Returns true if the target will correctly handle shrink wrapping.
70  bool enableShrinkWrapping(const MachineFunction &MF) const override {
71    return true;
72  }
73
74  bool enableStackSlotScavenging(const MachineFunction &MF) const override;
75  TargetStackID::Value getStackIDForScalableVectors() const override;
76
77  void processFunctionBeforeFrameFinalized(MachineFunction &MF,
78                                             RegScavenger *RS) const override;
79
80  unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override;
81
82  unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const;
83
84  int getFrameIndexReferencePreferSP(const MachineFunction &MF, int FI,
85                                     unsigned &FrameReg,
86                                     bool IgnoreSPUpdates) const override;
87  int getNonLocalFrameIndexReference(const MachineFunction &MF,
88                               int FI) const override;
89  int getSEHFrameIndexOffset(const MachineFunction &MF, int FI) const;
90
91  bool isSupportedStackID(TargetStackID::Value ID) const override {
92    switch (ID) {
93    default:
94      return false;
95    case TargetStackID::Default:
96    case TargetStackID::SVEVector:
97    case TargetStackID::NoAlloc:
98      return true;
99    }
100  }
101
102private:
103  bool shouldCombineCSRLocalStackBump(MachineFunction &MF,
104                                      uint64_t StackBumpBytes) const;
105
106  int64_t estimateSVEStackObjectOffsets(MachineFrameInfo &MF) const;
107  int64_t assignSVEStackObjectOffsets(MachineFrameInfo &MF,
108                                      int &MinCSFrameIndex,
109                                      int &MaxCSFrameIndex) const;
110};
111
112} // End llvm namespace
113
114#endif
115