106f32e7eSjoerg //==- AArch64RegisterInfo.h - AArch64 Register Information Impl --*- C++ -*-==//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file contains the AArch64 implementation of the MRegisterInfo class.
1006f32e7eSjoerg //
1106f32e7eSjoerg //===----------------------------------------------------------------------===//
1206f32e7eSjoerg 
1306f32e7eSjoerg #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64REGISTERINFO_H
1406f32e7eSjoerg #define LLVM_LIB_TARGET_AARCH64_AARCH64REGISTERINFO_H
1506f32e7eSjoerg 
1606f32e7eSjoerg #define GET_REGINFO_HEADER
1706f32e7eSjoerg #include "AArch64GenRegisterInfo.inc"
1806f32e7eSjoerg 
1906f32e7eSjoerg namespace llvm {
2006f32e7eSjoerg 
2106f32e7eSjoerg class MachineFunction;
2206f32e7eSjoerg class RegScavenger;
2306f32e7eSjoerg class TargetRegisterClass;
2406f32e7eSjoerg class Triple;
2506f32e7eSjoerg 
2606f32e7eSjoerg class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
2706f32e7eSjoerg   const Triple &TT;
2806f32e7eSjoerg 
2906f32e7eSjoerg public:
3006f32e7eSjoerg   AArch64RegisterInfo(const Triple &TT);
3106f32e7eSjoerg 
3206f32e7eSjoerg   // FIXME: This should be tablegen'd like getDwarfRegNum is
getSEHRegNum(unsigned i)3306f32e7eSjoerg   int getSEHRegNum(unsigned i) const {
3406f32e7eSjoerg     return getEncodingValue(i);
3506f32e7eSjoerg   }
3606f32e7eSjoerg 
37*da58b97aSjoerg   bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const;
3806f32e7eSjoerg   bool isAnyArgRegReserved(const MachineFunction &MF) const;
3906f32e7eSjoerg   void emitReservedArgRegCallError(const MachineFunction &MF) const;
4006f32e7eSjoerg 
4106f32e7eSjoerg   void UpdateCustomCalleeSavedRegs(MachineFunction &MF) const;
4206f32e7eSjoerg   void UpdateCustomCallPreservedMask(MachineFunction &MF,
4306f32e7eSjoerg                                      const uint32_t **Mask) const;
4406f32e7eSjoerg 
45*da58b97aSjoerg   static bool hasSVEArgsOrReturn(const MachineFunction *MF);
46*da58b97aSjoerg 
4706f32e7eSjoerg   /// Code Generation virtual methods...
4806f32e7eSjoerg   const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
49*da58b97aSjoerg   const MCPhysReg *getDarwinCalleeSavedRegs(const MachineFunction *MF) const;
5006f32e7eSjoerg   const MCPhysReg *
5106f32e7eSjoerg   getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
5206f32e7eSjoerg   const uint32_t *getCallPreservedMask(const MachineFunction &MF,
5306f32e7eSjoerg                                        CallingConv::ID) const override;
54*da58b97aSjoerg   const uint32_t *getDarwinCallPreservedMask(const MachineFunction &MF,
55*da58b97aSjoerg                                              CallingConv::ID) const;
5606f32e7eSjoerg 
getCSRFirstUseCost()5706f32e7eSjoerg   unsigned getCSRFirstUseCost() const override {
5806f32e7eSjoerg     // The cost will be compared against BlockFrequency where entry has the
5906f32e7eSjoerg     // value of 1 << 14. A value of 5 will choose to spill or split really
6006f32e7eSjoerg     // cold path instead of using a callee-saved register.
6106f32e7eSjoerg     return 5;
6206f32e7eSjoerg   }
6306f32e7eSjoerg 
6406f32e7eSjoerg   const TargetRegisterClass *
6506f32e7eSjoerg   getSubClassWithSubReg(const TargetRegisterClass *RC,
6606f32e7eSjoerg                         unsigned Idx) const override;
6706f32e7eSjoerg 
6806f32e7eSjoerg   // Calls involved in thread-local variable lookup save more registers than
6906f32e7eSjoerg   // normal calls, so they need a different mask to represent this.
7006f32e7eSjoerg   const uint32_t *getTLSCallPreservedMask() const;
7106f32e7eSjoerg 
7206f32e7eSjoerg   // Funclets on ARM64 Windows don't preserve any registers.
7306f32e7eSjoerg   const uint32_t *getNoPreservedMask() const override;
7406f32e7eSjoerg 
75*da58b97aSjoerg   // Unwinders may not preserve all Neon and SVE registers.
76*da58b97aSjoerg   const uint32_t *
77*da58b97aSjoerg   getCustomEHPadPreservedMask(const MachineFunction &MF) const override;
78*da58b97aSjoerg 
7906f32e7eSjoerg   /// getThisReturnPreservedMask - Returns a call preserved mask specific to the
8006f32e7eSjoerg   /// case that 'returned' is on an i64 first argument if the calling convention
8106f32e7eSjoerg   /// is one that can (partially) model this attribute with a preserved mask
8206f32e7eSjoerg   /// (i.e. it is a calling convention that uses the same register for the first
8306f32e7eSjoerg   /// i64 argument and an i64 return value)
8406f32e7eSjoerg   ///
8506f32e7eSjoerg   /// Should return NULL in the case that the calling convention does not have
8606f32e7eSjoerg   /// this property
8706f32e7eSjoerg   const uint32_t *getThisReturnPreservedMask(const MachineFunction &MF,
8806f32e7eSjoerg                                              CallingConv::ID) const;
8906f32e7eSjoerg 
9006f32e7eSjoerg   /// Stack probing calls preserve different CSRs to the normal CC.
9106f32e7eSjoerg   const uint32_t *getWindowsStackProbePreservedMask() const;
9206f32e7eSjoerg 
9306f32e7eSjoerg   BitVector getReservedRegs(const MachineFunction &MF) const override;
9406f32e7eSjoerg   bool isAsmClobberable(const MachineFunction &MF,
95*da58b97aSjoerg                        MCRegister PhysReg) const override;
96*da58b97aSjoerg   bool isConstantPhysReg(MCRegister PhysReg) const override;
9706f32e7eSjoerg   const TargetRegisterClass *
9806f32e7eSjoerg   getPointerRegClass(const MachineFunction &MF,
9906f32e7eSjoerg                      unsigned Kind = 0) const override;
10006f32e7eSjoerg   const TargetRegisterClass *
10106f32e7eSjoerg   getCrossCopyRegClass(const TargetRegisterClass *RC) const override;
10206f32e7eSjoerg 
10306f32e7eSjoerg   bool requiresRegisterScavenging(const MachineFunction &MF) const override;
10406f32e7eSjoerg   bool useFPForScavengingIndex(const MachineFunction &MF) const override;
10506f32e7eSjoerg   bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
10606f32e7eSjoerg 
10706f32e7eSjoerg   bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;
108*da58b97aSjoerg   bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,
10906f32e7eSjoerg                           int64_t Offset) const override;
110*da58b97aSjoerg   Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,
11106f32e7eSjoerg                                         int64_t Offset) const override;
112*da58b97aSjoerg   void resolveFrameIndex(MachineInstr &MI, Register BaseReg,
11306f32e7eSjoerg                          int64_t Offset) const override;
11406f32e7eSjoerg   void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
11506f32e7eSjoerg                            unsigned FIOperandNum,
11606f32e7eSjoerg                            RegScavenger *RS = nullptr) const override;
11706f32e7eSjoerg   bool cannotEliminateFrame(const MachineFunction &MF) const;
11806f32e7eSjoerg 
11906f32e7eSjoerg   bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override;
12006f32e7eSjoerg   bool hasBasePointer(const MachineFunction &MF) const;
12106f32e7eSjoerg   unsigned getBaseRegister() const;
12206f32e7eSjoerg 
12306f32e7eSjoerg   // Debug information queries.
12406f32e7eSjoerg   Register getFrameRegister(const MachineFunction &MF) const override;
12506f32e7eSjoerg 
12606f32e7eSjoerg   unsigned getRegPressureLimit(const TargetRegisterClass *RC,
12706f32e7eSjoerg                                MachineFunction &MF) const override;
12806f32e7eSjoerg 
12906f32e7eSjoerg   unsigned getLocalAddressRegister(const MachineFunction &MF) const;
130*da58b97aSjoerg   bool regNeedsCFI(unsigned Reg, unsigned &RegToUseForCFI) const;
131*da58b97aSjoerg 
132*da58b97aSjoerg   /// SrcRC and DstRC will be morphed into NewRC if this returns true
133*da58b97aSjoerg   bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC,
134*da58b97aSjoerg                       unsigned SubReg, const TargetRegisterClass *DstRC,
135*da58b97aSjoerg                       unsigned DstSubReg, const TargetRegisterClass *NewRC,
136*da58b97aSjoerg                       LiveIntervals &LIS) const override;
137*da58b97aSjoerg 
138*da58b97aSjoerg   void getOffsetOpcodes(const StackOffset &Offset,
139*da58b97aSjoerg                         SmallVectorImpl<uint64_t> &Ops) const override;
14006f32e7eSjoerg };
14106f32e7eSjoerg 
14206f32e7eSjoerg } // end namespace llvm
14306f32e7eSjoerg 
14406f32e7eSjoerg #endif
145