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