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.
isARMArea1Register(unsigned Reg,bool isIOS)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
isARMArea2Register(unsigned Reg,bool isIOS)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
isARMArea3Register(unsigned Reg,bool isIOS)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
isCalleeSavedRegister(unsigned Reg,const MCPhysReg * CSRegs)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;
getBaseRegister()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