1 //===-- ARMBaseRegisterInfo.h - ARM Register Information Impl ---*- 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 // This file contains the base ARM implementation of TargetRegisterInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H 14 #define LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H 15 16 #include "MCTargetDesc/ARMBaseInfo.h" 17 #include "llvm/CodeGen/MachineBasicBlock.h" 18 #include "llvm/CodeGen/MachineInstr.h" 19 #include "llvm/CodeGen/TargetRegisterInfo.h" 20 #include "llvm/IR/CallingConv.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include <cstdint> 23 24 #define GET_REGINFO_HEADER 25 #include "ARMGenRegisterInfo.inc" 26 27 namespace llvm { 28 29 class LiveIntervals; 30 31 /// Register allocation hints. 32 namespace ARMRI { 33 34 enum { 35 RegPairOdd = 1, 36 RegPairEven = 2 37 }; 38 39 } // end namespace ARMRI 40 41 /// isARMArea1Register - Returns true if the register is a low register (r0-r7) 42 /// or a stack/pc register that we should push/pop. 43 static inline bool isARMArea1Register(unsigned Reg, bool isIOS) { 44 using namespace ARM; 45 46 switch (Reg) { 47 case R0: case R1: case R2: case R3: 48 case R4: case R5: case R6: case R7: 49 case LR: case SP: case PC: 50 return true; 51 case R8: case R9: case R10: case R11: case R12: 52 // For iOS we want r7 and lr to be next to each other. 53 return !isIOS; 54 default: 55 return false; 56 } 57 } 58 59 static inline bool isARMArea2Register(unsigned Reg, bool isIOS) { 60 using namespace ARM; 61 62 switch (Reg) { 63 case R8: case R9: case R10: case R11: case R12: 64 // iOS has this second area. 65 return isIOS; 66 default: 67 return false; 68 } 69 } 70 71 static inline bool isARMArea3Register(unsigned Reg, bool isIOS) { 72 using namespace ARM; 73 74 switch (Reg) { 75 case D15: case D14: case D13: case D12: 76 case D11: case D10: case D9: case D8: 77 case D7: case D6: case D5: case D4: 78 case D3: case D2: case D1: case D0: 79 case D31: case D30: case D29: case D28: 80 case D27: case D26: case D25: case D24: 81 case D23: case D22: case D21: case D20: 82 case D19: case D18: case D17: case D16: 83 return true; 84 default: 85 return false; 86 } 87 } 88 89 static inline bool isCalleeSavedRegister(unsigned Reg, 90 const MCPhysReg *CSRegs) { 91 for (unsigned i = 0; CSRegs[i]; ++i) 92 if (Reg == CSRegs[i]) 93 return true; 94 return false; 95 } 96 97 class ARMBaseRegisterInfo : public ARMGenRegisterInfo { 98 protected: 99 /// BasePtr - ARM physical register used as a base ptr in complex stack 100 /// frames. I.e., when we need a 3rd base, not just SP and FP, due to 101 /// variable size stack objects. 102 unsigned BasePtr = ARM::R6; 103 104 // Can be only subclassed. 105 explicit ARMBaseRegisterInfo(); 106 107 // Return the opcode that implements 'Op', or 0 if no opcode 108 unsigned getOpcode(int Op) const; 109 110 public: 111 /// Code Generation virtual methods... 112 const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; 113 const MCPhysReg * 114 getCalleeSavedRegsViaCopy(const MachineFunction *MF) const; 115 const uint32_t *getCallPreservedMask(const MachineFunction &MF, 116 CallingConv::ID) const override; 117 const uint32_t *getNoPreservedMask() const override; 118 const uint32_t *getTLSCallPreservedMask(const MachineFunction &MF) const; 119 const uint32_t *getSjLjDispatchPreservedMask(const MachineFunction &MF) const; 120 121 /// getThisReturnPreservedMask - Returns a call preserved mask specific to the 122 /// case that 'returned' is on an i32 first argument if the calling convention 123 /// is one that can (partially) model this attribute with a preserved mask 124 /// (i.e. it is a calling convention that uses the same register for the first 125 /// i32 argument and an i32 return value) 126 /// 127 /// Should return NULL in the case that the calling convention does not have 128 /// this property 129 const uint32_t *getThisReturnPreservedMask(const MachineFunction &MF, 130 CallingConv::ID) const; 131 132 ArrayRef<MCPhysReg> 133 getIntraCallClobberedRegs(const MachineFunction *MF) const override; 134 135 BitVector getReservedRegs(const MachineFunction &MF) const override; 136 bool isAsmClobberable(const MachineFunction &MF, 137 unsigned PhysReg) const override; 138 139 const TargetRegisterClass * 140 getPointerRegClass(const MachineFunction &MF, 141 unsigned Kind = 0) const override; 142 const TargetRegisterClass * 143 getCrossCopyRegClass(const TargetRegisterClass *RC) const override; 144 145 const TargetRegisterClass * 146 getLargestLegalSuperClass(const TargetRegisterClass *RC, 147 const MachineFunction &MF) const override; 148 149 unsigned getRegPressureLimit(const TargetRegisterClass *RC, 150 MachineFunction &MF) const override; 151 152 bool getRegAllocationHints(unsigned VirtReg, 153 ArrayRef<MCPhysReg> Order, 154 SmallVectorImpl<MCPhysReg> &Hints, 155 const MachineFunction &MF, 156 const VirtRegMap *VRM, 157 const LiveRegMatrix *Matrix) const override; 158 159 void updateRegAllocHint(unsigned Reg, unsigned NewReg, 160 MachineFunction &MF) const override; 161 162 bool hasBasePointer(const MachineFunction &MF) const; 163 164 bool canRealignStack(const MachineFunction &MF) const override; 165 int64_t getFrameIndexInstrOffset(const MachineInstr *MI, 166 int Idx) const override; 167 bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; 168 void materializeFrameBaseRegister(MachineBasicBlock *MBB, 169 unsigned BaseReg, int FrameIdx, 170 int64_t Offset) const override; 171 void resolveFrameIndex(MachineInstr &MI, unsigned BaseReg, 172 int64_t Offset) const override; 173 bool isFrameOffsetLegal(const MachineInstr *MI, unsigned BaseReg, 174 int64_t Offset) const override; 175 176 bool cannotEliminateFrame(const MachineFunction &MF) const; 177 178 // Debug information queries. 179 Register getFrameRegister(const MachineFunction &MF) const override; 180 unsigned getBaseRegister() const { return BasePtr; } 181 182 183 /// emitLoadConstPool - Emits a load from constpool to materialize the 184 /// specified immediate. 185 virtual void 186 emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 187 const DebugLoc &dl, unsigned DestReg, unsigned SubIdx, 188 int Val, ARMCC::CondCodes Pred = ARMCC::AL, 189 unsigned PredReg = 0, 190 unsigned MIFlags = MachineInstr::NoFlags) const; 191 192 /// Code Generation virtual methods... 193 bool requiresRegisterScavenging(const MachineFunction &MF) const override; 194 195 bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const override; 196 197 bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; 198 199 bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override; 200 201 void eliminateFrameIndex(MachineBasicBlock::iterator II, 202 int SPAdj, unsigned FIOperandNum, 203 RegScavenger *RS = nullptr) const override; 204 205 /// SrcRC and DstRC will be morphed into NewRC if this returns true 206 bool shouldCoalesce(MachineInstr *MI, 207 const TargetRegisterClass *SrcRC, 208 unsigned SubReg, 209 const TargetRegisterClass *DstRC, 210 unsigned DstSubReg, 211 const TargetRegisterClass *NewRC, 212 LiveIntervals &LIS) const override; 213 }; 214 215 } // end namespace llvm 216 217 #endif // LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H 218