Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
96353 views
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
const TargetRegisterClass *
245
getLargestSuperClass(const TargetRegisterClass *RC) const override {
246
if (ARM::MQPRRegClass.hasSubClassEq(RC))
247
return &ARM::MQPRRegClass;
248
if (ARM::SPRRegClass.hasSubClassEq(RC))
249
return &ARM::SPRRegClass;
250
if (ARM::DPR_VFP2RegClass.hasSubClassEq(RC))
251
return &ARM::DPR_VFP2RegClass;
252
if (ARM::GPRRegClass.hasSubClassEq(RC))
253
return &ARM::GPRRegClass;
254
return RC;
255
}
256
257
bool doesRegClassHavePseudoInitUndef(
258
const TargetRegisterClass *RC) const override {
259
(void)RC;
260
// For the ARM Architecture we want to always return true because all
261
// required PseudoInitUndef types have been added. If compilation fails due
262
// to `Unexpected register class`, this is likely to be because the specific
263
// register being used is not support by Init Undef and needs the Pseudo
264
// Instruction adding to ARMInstrInfo.td. If this is implemented as a
265
// conditional check, this could create a false positive where Init Undef is
266
// not running, skipping the instruction and moving to the next. This could
267
// lead to illegal instructions being generated by the register allocator.
268
return true;
269
}
270
};
271
272
} // end namespace llvm
273
274
#endif // LLVM_LIB_TARGET_ARM_ARMBASEREGISTERINFO_H
275
276