Path: blob/main/contrib/llvm-project/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
96353 views
//===-- ARMBaseRegisterInfo.h - ARM Register Information Impl ---*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the base ARM implementation of TargetRegisterInfo class.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H13#define LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H1415#include "MCTargetDesc/ARMBaseInfo.h"16#include "llvm/CodeGen/MachineBasicBlock.h"17#include "llvm/CodeGen/MachineInstr.h"18#include "llvm/CodeGen/TargetRegisterInfo.h"19#include "llvm/IR/CallingConv.h"20#include "llvm/MC/MCRegisterInfo.h"21#include <cstdint>2223#define GET_REGINFO_HEADER24#include "ARMGenRegisterInfo.inc"2526namespace llvm {2728class LiveIntervals;2930/// Register allocation hints.31namespace ARMRI {3233enum {34// Used for LDRD register pairs35RegPairOdd = 1,36RegPairEven = 2,37// Used to hint for lr in t2DoLoopStart38RegLR = 339};4041} // end namespace ARMRI4243/// isARMArea1Register - Returns true if the register is a low register (r0-r7)44/// or a stack/pc register that we should push/pop.45static inline bool isARMArea1Register(unsigned Reg, bool SplitFramePushPop) {46using namespace ARM;4748switch (Reg) {49case R0: case R1: case R2: case R3:50case R4: case R5: case R6: case R7:51case LR: case SP: case PC:52return true;53case R8: case R9: case R10: case R11: case R12:54// For iOS we want r7 and lr to be next to each other.55return !SplitFramePushPop;56default:57return false;58}59}6061static inline bool isARMArea2Register(unsigned Reg, bool SplitFramePushPop) {62using namespace ARM;6364switch (Reg) {65case R8: case R9: case R10: case R11: case R12:66// iOS has this second area.67return SplitFramePushPop;68default:69return false;70}71}7273static inline bool isSplitFPArea1Register(unsigned Reg,74bool SplitFramePushPop) {75using namespace ARM;7677switch (Reg) {78case R0: case R1: case R2: case R3:79case R4: case R5: case R6: case R7:80case R8: case R9: case R10: case R12:81case SP: case PC:82return true;83default:84return false;85}86}8788static inline bool isSplitFPArea2Register(unsigned Reg,89bool SplitFramePushPop) {90using namespace ARM;9192switch (Reg) {93case R11: case LR:94return true;95default:96return false;97}98}99100static inline bool isARMArea3Register(unsigned Reg, bool SplitFramePushPop) {101using namespace ARM;102103switch (Reg) {104case D15: case D14: case D13: case D12:105case D11: case D10: case D9: case D8:106case D7: case D6: case D5: case D4:107case D3: case D2: case D1: case D0:108case D31: case D30: case D29: case D28:109case D27: case D26: case D25: case D24:110case D23: case D22: case D21: case D20:111case D19: case D18: case D17: case D16:112return true;113default:114return false;115}116}117118static inline bool isCalleeSavedRegister(unsigned Reg,119const MCPhysReg *CSRegs) {120for (unsigned i = 0; CSRegs[i]; ++i)121if (Reg == CSRegs[i])122return true;123return false;124}125126class ARMBaseRegisterInfo : public ARMGenRegisterInfo {127protected:128/// BasePtr - ARM physical register used as a base ptr in complex stack129/// frames. I.e., when we need a 3rd base, not just SP and FP, due to130/// variable size stack objects.131unsigned BasePtr = ARM::R6;132133// Can be only subclassed.134explicit ARMBaseRegisterInfo();135136public:137/// Code Generation virtual methods...138const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;139const MCPhysReg *140getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;141const uint32_t *getCallPreservedMask(const MachineFunction &MF,142CallingConv::ID) const override;143const uint32_t *getNoPreservedMask() const override;144const uint32_t *getTLSCallPreservedMask(const MachineFunction &MF) const;145const uint32_t *getSjLjDispatchPreservedMask(const MachineFunction &MF) const;146147/// getThisReturnPreservedMask - Returns a call preserved mask specific to the148/// case that 'returned' is on an i32 first argument if the calling convention149/// is one that can (partially) model this attribute with a preserved mask150/// (i.e. it is a calling convention that uses the same register for the first151/// i32 argument and an i32 return value)152///153/// Should return NULL in the case that the calling convention does not have154/// this property155const uint32_t *getThisReturnPreservedMask(const MachineFunction &MF,156CallingConv::ID) const;157158ArrayRef<MCPhysReg>159getIntraCallClobberedRegs(const MachineFunction *MF) const override;160161BitVector getReservedRegs(const MachineFunction &MF) const override;162bool isAsmClobberable(const MachineFunction &MF,163MCRegister PhysReg) const override;164bool isInlineAsmReadOnlyReg(const MachineFunction &MF,165unsigned PhysReg) const override;166167const TargetRegisterClass *168getPointerRegClass(const MachineFunction &MF,169unsigned Kind = 0) const override;170const TargetRegisterClass *171getCrossCopyRegClass(const TargetRegisterClass *RC) const override;172173const TargetRegisterClass *174getLargestLegalSuperClass(const TargetRegisterClass *RC,175const MachineFunction &MF) const override;176177unsigned getRegPressureLimit(const TargetRegisterClass *RC,178MachineFunction &MF) const override;179180bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order,181SmallVectorImpl<MCPhysReg> &Hints,182const MachineFunction &MF, const VirtRegMap *VRM,183const LiveRegMatrix *Matrix) const override;184185void updateRegAllocHint(Register Reg, Register NewReg,186MachineFunction &MF) const override;187188bool hasBasePointer(const MachineFunction &MF) const;189190bool canRealignStack(const MachineFunction &MF) const override;191int64_t getFrameIndexInstrOffset(const MachineInstr *MI,192int Idx) const override;193bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override;194Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx,195int64_t Offset) const override;196void resolveFrameIndex(MachineInstr &MI, Register BaseReg,197int64_t Offset) const override;198bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg,199int64_t Offset) const override;200201bool cannotEliminateFrame(const MachineFunction &MF) const;202203// Debug information queries.204Register getFrameRegister(const MachineFunction &MF) const override;205Register getBaseRegister() const { return BasePtr; }206207/// emitLoadConstPool - Emits a load from constpool to materialize the208/// specified immediate.209virtual void210emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,211const DebugLoc &dl, Register DestReg, unsigned SubIdx,212int Val, ARMCC::CondCodes Pred = ARMCC::AL,213Register PredReg = Register(),214unsigned MIFlags = MachineInstr::NoFlags) const;215216/// Code Generation virtual methods...217bool requiresRegisterScavenging(const MachineFunction &MF) const override;218219bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;220221bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override;222223bool eliminateFrameIndex(MachineBasicBlock::iterator II,224int SPAdj, unsigned FIOperandNum,225RegScavenger *RS = nullptr) const override;226227/// SrcRC and DstRC will be morphed into NewRC if this returns true228bool shouldCoalesce(MachineInstr *MI,229const TargetRegisterClass *SrcRC,230unsigned SubReg,231const TargetRegisterClass *DstRC,232unsigned DstSubReg,233const TargetRegisterClass *NewRC,234LiveIntervals &LIS) const override;235236bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC,237unsigned DefSubReg,238const TargetRegisterClass *SrcRC,239unsigned SrcSubReg) const override;240241int getSEHRegNum(unsigned i) const { return getEncodingValue(i); }242243const TargetRegisterClass *244getLargestSuperClass(const TargetRegisterClass *RC) const override {245if (ARM::MQPRRegClass.hasSubClassEq(RC))246return &ARM::MQPRRegClass;247if (ARM::SPRRegClass.hasSubClassEq(RC))248return &ARM::SPRRegClass;249if (ARM::DPR_VFP2RegClass.hasSubClassEq(RC))250return &ARM::DPR_VFP2RegClass;251if (ARM::GPRRegClass.hasSubClassEq(RC))252return &ARM::GPRRegClass;253return RC;254}255256bool doesRegClassHavePseudoInitUndef(257const TargetRegisterClass *RC) const override {258(void)RC;259// For the ARM Architecture we want to always return true because all260// required PseudoInitUndef types have been added. If compilation fails due261// to `Unexpected register class`, this is likely to be because the specific262// register being used is not support by Init Undef and needs the Pseudo263// Instruction adding to ARMInstrInfo.td. If this is implemented as a264// conditional check, this could create a false positive where Init Undef is265// not running, skipping the instruction and moving to the next. This could266// lead to illegal instructions being generated by the register allocator.267return true;268}269};270271} // end namespace llvm272273#endif // LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H274275276