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