10b57cec5SDimitry Andric //==- AArch64RegisterInfo.h - AArch64 Register Information Impl --*- C++ -*-==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the AArch64 implementation of the MRegisterInfo class. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AARCH64_AARCH64REGISTERINFO_H 140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AARCH64_AARCH64REGISTERINFO_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #define GET_REGINFO_HEADER 170b57cec5SDimitry Andric #include "AArch64GenRegisterInfo.inc" 180b57cec5SDimitry Andric 190b57cec5SDimitry Andric namespace llvm { 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric class MachineFunction; 220b57cec5SDimitry Andric class RegScavenger; 230b57cec5SDimitry Andric class TargetRegisterClass; 240b57cec5SDimitry Andric class Triple; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric class AArch64RegisterInfo final : public AArch64GenRegisterInfo { 270b57cec5SDimitry Andric const Triple &TT; 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric public: 300b57cec5SDimitry Andric AArch64RegisterInfo(const Triple &TT); 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric // FIXME: This should be tablegen'd like getDwarfRegNum is 330b57cec5SDimitry Andric int getSEHRegNum(unsigned i) const { 340b57cec5SDimitry Andric return getEncodingValue(i); 350b57cec5SDimitry Andric } 360b57cec5SDimitry Andric 375ffd83dbSDimitry Andric bool isReservedReg(const MachineFunction &MF, MCRegister Reg) const; 38bdd1243dSDimitry Andric bool isStrictlyReservedReg(const MachineFunction &MF, MCRegister Reg) const; 390b57cec5SDimitry Andric bool isAnyArgRegReserved(const MachineFunction &MF) const; 400b57cec5SDimitry Andric void emitReservedArgRegCallError(const MachineFunction &MF) const; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric void UpdateCustomCalleeSavedRegs(MachineFunction &MF) const; 430b57cec5SDimitry Andric void UpdateCustomCallPreservedMask(MachineFunction &MF, 440b57cec5SDimitry Andric const uint32_t **Mask) const; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric /// Code Generation virtual methods... 470b57cec5SDimitry Andric const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; 485ffd83dbSDimitry Andric const MCPhysReg *getDarwinCalleeSavedRegs(const MachineFunction *MF) const; 490b57cec5SDimitry Andric const MCPhysReg * 500b57cec5SDimitry Andric getCalleeSavedRegsViaCopy(const MachineFunction *MF) const; 510b57cec5SDimitry Andric const uint32_t *getCallPreservedMask(const MachineFunction &MF, 520b57cec5SDimitry Andric CallingConv::ID) const override; 535ffd83dbSDimitry Andric const uint32_t *getDarwinCallPreservedMask(const MachineFunction &MF, 545ffd83dbSDimitry Andric CallingConv::ID) const; 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric unsigned getCSRFirstUseCost() const override { 570b57cec5SDimitry Andric // The cost will be compared against BlockFrequency where entry has the 580b57cec5SDimitry Andric // value of 1 << 14. A value of 5 will choose to spill or split really 590b57cec5SDimitry Andric // cold path instead of using a callee-saved register. 600b57cec5SDimitry Andric return 5; 610b57cec5SDimitry Andric } 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric const TargetRegisterClass * 640b57cec5SDimitry Andric getSubClassWithSubReg(const TargetRegisterClass *RC, 650b57cec5SDimitry Andric unsigned Idx) const override; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric // Calls involved in thread-local variable lookup save more registers than 680b57cec5SDimitry Andric // normal calls, so they need a different mask to represent this. 690b57cec5SDimitry Andric const uint32_t *getTLSCallPreservedMask() const; 700b57cec5SDimitry Andric 71bdd1243dSDimitry Andric const uint32_t *getSMStartStopCallPreservedMask() const; 72bdd1243dSDimitry Andric const uint32_t *SMEABISupportRoutinesCallPreservedMaskFromX0() const; 73bdd1243dSDimitry Andric 740b57cec5SDimitry Andric // Funclets on ARM64 Windows don't preserve any registers. 750b57cec5SDimitry Andric const uint32_t *getNoPreservedMask() const override; 760b57cec5SDimitry Andric 77e8d8bef9SDimitry Andric // Unwinders may not preserve all Neon and SVE registers. 78e8d8bef9SDimitry Andric const uint32_t * 79e8d8bef9SDimitry Andric getCustomEHPadPreservedMask(const MachineFunction &MF) const override; 80e8d8bef9SDimitry Andric 810b57cec5SDimitry Andric /// getThisReturnPreservedMask - Returns a call preserved mask specific to the 820b57cec5SDimitry Andric /// case that 'returned' is on an i64 first argument if the calling convention 830b57cec5SDimitry Andric /// is one that can (partially) model this attribute with a preserved mask 840b57cec5SDimitry Andric /// (i.e. it is a calling convention that uses the same register for the first 850b57cec5SDimitry Andric /// i64 argument and an i64 return value) 860b57cec5SDimitry Andric /// 870b57cec5SDimitry Andric /// Should return NULL in the case that the calling convention does not have 880b57cec5SDimitry Andric /// this property 890b57cec5SDimitry Andric const uint32_t *getThisReturnPreservedMask(const MachineFunction &MF, 900b57cec5SDimitry Andric CallingConv::ID) const; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric /// Stack probing calls preserve different CSRs to the normal CC. 930b57cec5SDimitry Andric const uint32_t *getWindowsStackProbePreservedMask() const; 940b57cec5SDimitry Andric 95bdd1243dSDimitry Andric BitVector getStrictlyReservedRegs(const MachineFunction &MF) const; 960b57cec5SDimitry Andric BitVector getReservedRegs(const MachineFunction &MF) const override; 97bdd1243dSDimitry Andric std::optional<std::string> 98bdd1243dSDimitry Andric explainReservedReg(const MachineFunction &MF, 99bdd1243dSDimitry Andric MCRegister PhysReg) const override; 1000b57cec5SDimitry Andric bool isAsmClobberable(const MachineFunction &MF, 1015ffd83dbSDimitry Andric MCRegister PhysReg) const override; 1020b57cec5SDimitry Andric const TargetRegisterClass * 1030b57cec5SDimitry Andric getPointerRegClass(const MachineFunction &MF, 1040b57cec5SDimitry Andric unsigned Kind = 0) const override; 1050b57cec5SDimitry Andric const TargetRegisterClass * 1060b57cec5SDimitry Andric getCrossCopyRegClass(const TargetRegisterClass *RC) const override; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric bool requiresRegisterScavenging(const MachineFunction &MF) const override; 1090b57cec5SDimitry Andric bool useFPForScavengingIndex(const MachineFunction &MF) const override; 1100b57cec5SDimitry Andric bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; 1135ffd83dbSDimitry Andric bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, 1140b57cec5SDimitry Andric int64_t Offset) const override; 115e8d8bef9SDimitry Andric Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, 1160b57cec5SDimitry Andric int64_t Offset) const override; 1175ffd83dbSDimitry Andric void resolveFrameIndex(MachineInstr &MI, Register BaseReg, 1180b57cec5SDimitry Andric int64_t Offset) const override; 119bdd1243dSDimitry Andric bool eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, 1200b57cec5SDimitry Andric unsigned FIOperandNum, 1210b57cec5SDimitry Andric RegScavenger *RS = nullptr) const override; 1220b57cec5SDimitry Andric bool cannotEliminateFrame(const MachineFunction &MF) const; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override; 1250b57cec5SDimitry Andric bool hasBasePointer(const MachineFunction &MF) const; 1260b57cec5SDimitry Andric unsigned getBaseRegister() const; 1270b57cec5SDimitry Andric 12881ad6265SDimitry Andric bool isArgumentRegister(const MachineFunction &MF, 12981ad6265SDimitry Andric MCRegister Reg) const override; 13081ad6265SDimitry Andric 1310b57cec5SDimitry Andric // Debug information queries. 1320b57cec5SDimitry Andric Register getFrameRegister(const MachineFunction &MF) const override; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric unsigned getRegPressureLimit(const TargetRegisterClass *RC, 1350b57cec5SDimitry Andric MachineFunction &MF) const override; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric unsigned getLocalAddressRegister(const MachineFunction &MF) const; 13875b4d546SDimitry Andric bool regNeedsCFI(unsigned Reg, unsigned &RegToUseForCFI) const; 139e8d8bef9SDimitry Andric 140e8d8bef9SDimitry Andric /// SrcRC and DstRC will be morphed into NewRC if this returns true 141e8d8bef9SDimitry Andric bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, 142e8d8bef9SDimitry Andric unsigned SubReg, const TargetRegisterClass *DstRC, 143e8d8bef9SDimitry Andric unsigned DstSubReg, const TargetRegisterClass *NewRC, 144e8d8bef9SDimitry Andric LiveIntervals &LIS) const override; 145e8d8bef9SDimitry Andric 146e8d8bef9SDimitry Andric void getOffsetOpcodes(const StackOffset &Offset, 147e8d8bef9SDimitry Andric SmallVectorImpl<uint64_t> &Ops) const override; 148*0fca6ea1SDimitry Andric 149*0fca6ea1SDimitry Andric bool shouldAnalyzePhysregInMachineLoopInfo(MCRegister R) const override; 1500b57cec5SDimitry Andric }; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric } // end namespace llvm 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric #endif 155