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 // Return the opcode that implements 'Op', or 0 if no opcode 138 unsigned getOpcode(int Op) const; 139 140 public: 141 /// Code Generation virtual methods... 142 const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override; 143 const MCPhysReg * 144 getCalleeSavedRegsViaCopy(const MachineFunction *MF) const; 145 const uint32_t *getCallPreservedMask(const MachineFunction &MF, 146 CallingConv::ID) const override; 147 const uint32_t *getNoPreservedMask() const override; 148 const uint32_t *getTLSCallPreservedMask(const MachineFunction &MF) const; 149 const uint32_t *getSjLjDispatchPreservedMask(const MachineFunction &MF) const; 150 151 /// getThisReturnPreservedMask - Returns a call preserved mask specific to the 152 /// case that 'returned' is on an i32 first argument if the calling convention 153 /// is one that can (partially) model this attribute with a preserved mask 154 /// (i.e. it is a calling convention that uses the same register for the first 155 /// i32 argument and an i32 return value) 156 /// 157 /// Should return NULL in the case that the calling convention does not have 158 /// this property 159 const uint32_t *getThisReturnPreservedMask(const MachineFunction &MF, 160 CallingConv::ID) const; 161 162 ArrayRef<MCPhysReg> 163 getIntraCallClobberedRegs(const MachineFunction *MF) const override; 164 165 BitVector getReservedRegs(const MachineFunction &MF) const override; 166 bool isAsmClobberable(const MachineFunction &MF, 167 MCRegister PhysReg) const override; 168 bool isInlineAsmReadOnlyReg(const MachineFunction &MF, 169 unsigned PhysReg) const override; 170 171 const TargetRegisterClass * 172 getPointerRegClass(const MachineFunction &MF, 173 unsigned Kind = 0) const override; 174 const TargetRegisterClass * 175 getCrossCopyRegClass(const TargetRegisterClass *RC) const override; 176 177 const TargetRegisterClass * 178 getLargestLegalSuperClass(const TargetRegisterClass *RC, 179 const MachineFunction &MF) const override; 180 181 unsigned getRegPressureLimit(const TargetRegisterClass *RC, 182 MachineFunction &MF) const override; 183 184 bool getRegAllocationHints(Register VirtReg, ArrayRef<MCPhysReg> Order, 185 SmallVectorImpl<MCPhysReg> &Hints, 186 const MachineFunction &MF, const VirtRegMap *VRM, 187 const LiveRegMatrix *Matrix) const override; 188 189 void updateRegAllocHint(Register Reg, Register NewReg, 190 MachineFunction &MF) const override; 191 192 bool hasBasePointer(const MachineFunction &MF) const; 193 194 bool canRealignStack(const MachineFunction &MF) const override; 195 int64_t getFrameIndexInstrOffset(const MachineInstr *MI, 196 int Idx) const override; 197 bool needsFrameBaseReg(MachineInstr *MI, int64_t Offset) const override; 198 Register materializeFrameBaseRegister(MachineBasicBlock *MBB, int FrameIdx, 199 int64_t Offset) const override; 200 void resolveFrameIndex(MachineInstr &MI, Register BaseReg, 201 int64_t Offset) const override; 202 bool isFrameOffsetLegal(const MachineInstr *MI, Register BaseReg, 203 int64_t Offset) const override; 204 205 bool cannotEliminateFrame(const MachineFunction &MF) const; 206 207 // Debug information queries. 208 Register getFrameRegister(const MachineFunction &MF) const override; 209 Register getBaseRegister() const { return BasePtr; } 210 211 /// emitLoadConstPool - Emits a load from constpool to materialize the 212 /// specified immediate. 213 virtual void 214 emitLoadConstPool(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, 215 const DebugLoc &dl, Register DestReg, unsigned SubIdx, 216 int Val, ARMCC::CondCodes Pred = ARMCC::AL, 217 Register PredReg = Register(), 218 unsigned MIFlags = MachineInstr::NoFlags) const; 219 220 /// Code Generation virtual methods... 221 bool requiresRegisterScavenging(const MachineFunction &MF) const override; 222 223 bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; 224 225 bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override; 226 227 void eliminateFrameIndex(MachineBasicBlock::iterator II, 228 int SPAdj, unsigned FIOperandNum, 229 RegScavenger *RS = nullptr) const override; 230 231 /// SrcRC and DstRC will be morphed into NewRC if this returns true 232 bool shouldCoalesce(MachineInstr *MI, 233 const TargetRegisterClass *SrcRC, 234 unsigned SubReg, 235 const TargetRegisterClass *DstRC, 236 unsigned DstSubReg, 237 const TargetRegisterClass *NewRC, 238 LiveIntervals &LIS) const override; 239 240 bool shouldRewriteCopySrc(const TargetRegisterClass *DefRC, 241 unsigned DefSubReg, 242 const TargetRegisterClass *SrcRC, 243 unsigned SrcSubReg) const override; 244 245 int getSEHRegNum(unsigned i) const { return getEncodingValue(i); } 246 }; 247 248 } // end namespace llvm 249 250 #endif // LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H 251