LLVM: lib/Target/ARM/ARMCallingConv.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
17using namespace llvm;
18
19
22 CCState &State, bool CanFail) {
23 static const MCPhysReg RegList[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
24
25
28 else {
29
30 if (CanFail)
31 return false;
32
33
36 return true;
37 }
38
39
42 else
45 return true;
46}
47
52 if ((ValNo, ValVT, LocVT, LocInfo, State, true))
53 return false;
54 if (LocVT == MVT::v2f64 &&
55 (ValNo, ValVT, LocVT, LocInfo, State, false))
56 return false;
57 return true;
58}
59
60
63 CCState &State, bool CanFail) {
64 static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
65 static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
66 static const MCPhysReg ShadowRegList[] = { ARM::R0, ARM::R1 };
67 static const MCPhysReg GPRArgRegs[] = { ARM::R0, ARM::R1, ARM::R2, ARM::R3 };
68
70 if (!Reg) {
71
72
74 assert((!Reg || Reg == ARM::R3) && "Wrong GPRs usage for f64");
75
76
77 if (CanFail)
78 return false;
79
80
83 return true;
84 }
85
86 unsigned i;
87 for (i = 0; i < 2; ++i)
88 if (HiRegList[i] == Reg)
89 break;
90
92 (void)T;
93 assert(T == LoRegList[i] && "Could not allocate register");
94
97 LocVT, LocInfo));
98 return true;
99}
100
105 if ((ValNo, ValVT, LocVT, LocInfo, State, true))
106 return false;
107 if (LocVT == MVT::v2f64 &&
108 (ValNo, ValVT, LocVT, LocInfo, State, false))
109 return false;
110 return true;
111}
112
115 static const MCPhysReg HiRegList[] = { ARM::R0, ARM::R2 };
116 static const MCPhysReg LoRegList[] = { ARM::R1, ARM::R3 };
117
119 if (!Reg)
120 return false;
121
122 unsigned i;
123 for (i = 0; i < 2; ++i)
124 if (HiRegList[i] == Reg)
125 break;
126
129 LocVT, LocInfo));
130 return true;
131}
132
137 if ((ValNo, ValVT, LocVT, LocInfo, State))
138 return false;
139 if (LocVT == MVT::v2f64 && (ValNo, ValVT, LocVT, LocInfo, State))
140 return false;
141 return true;
142}
143
149 State);
150}
151
153
155 ARM::S4, ARM::S5, ARM::S6, ARM::S7,
156 ARM::S8, ARM::S9, ARM::S10, ARM::S11,
157 ARM::S12, ARM::S13, ARM::S14, ARM::S15 };
159 ARM::D4, ARM::D5, ARM::D6, ARM::D7 };
161
162
163
164
165
166
167
169 MVT LocVT,
174
175
176 if (PendingMembers.size() > 0)
177 assert(PendingMembers[0].getLocVT() == LocVT);
178
179
180
181
182
185
187 return true;
188
189
190
192 const MaybeAlign StackAlign = DL.getStackAlignment();
193 assert(StackAlign && "data layout string is missing stack alignment");
194 const Align FirstMemberAlign(PendingMembers[0].getExtraInfo());
195 Align Alignment = std::min(FirstMemberAlign, *StackAlign);
196
199 case MVT::i32: {
202
203
204
205 unsigned RegAlign = alignTo(Alignment.value(), 4) / 4;
206 while (RegIdx % RegAlign != 0 && RegIdx < RegList.size())
208
209 break;
210 }
211 case MVT::f16:
212 case MVT::bf16:
213 case MVT::f32:
215 break;
216 case MVT::v4f16:
217 case MVT::v4bf16:
218 case MVT::f64:
220 break;
221 case MVT::v8f16:
222 case MVT::v8bf16:
223 case MVT::v2f64:
225 break;
226 default:
227 llvm_unreachable("Unexpected member type for block aggregate");
228 break;
229 }
230
233 if (!RegResult.empty()) {
234 for (const auto &[PendingMember, Reg] : zip(PendingMembers, RegResult)) {
235 PendingMember.convertToReg(Reg);
236 State.addLoc(PendingMember);
237 }
238 PendingMembers.clear();
239 return true;
240 }
241
242
244 if (LocVT == MVT::i32 && State.getStackSize() == 0) {
245
246
248 for (auto &It : PendingMembers) {
249 if (RegIdx >= RegList.size())
251 else
252 It.convertToReg(State.AllocateReg(RegList[RegIdx++]));
253
255 }
256 PendingMembers.clear();
257 return true;
258 }
259
260 if (LocVT != MVT::i32)
262
263
264 for (auto Reg : RegList)
266
267
270
271
272
273
274 for (auto &It : PendingMembers) {
277 Alignment = Align(1);
278 }
279
280
281 PendingMembers.clear();
282
283
284 return true;
285}
286
291 if (Reg) {
293 return true;
294 }
295 return false;
296}
297
301
304}
305
310
313}
314
315
316#include "ARMGenCallingConv.inc"
static const MCPhysReg GPRArgRegs[]
static bool CC_ARM_AAPCS_VFP_Custom_f16(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool f64RetAssign(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, CCState &State)
static const MCPhysReg RRegList[]
static bool RetCC_ARM_AAPCS_Custom_f64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static const MCPhysReg SRegList[]
static bool CC_ARM_AAPCS_Custom_Aggregate(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool f64AssignAAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, CCState &State, bool CanFail)
static const MCPhysReg DRegList[]
static bool RetCC_ARM_APCS_Custom_f64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool CC_ARM_AAPCS_Custom_f64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool f64AssignAPCS(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, CCState &State, bool CanFail)
static const MCPhysReg QRegList[]
static bool CC_ARM_AAPCS_Custom_f16(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool CC_ARM_APCS_Custom_f64(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
static bool CustomAssignInRegList(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, CCState &State, ArrayRef< MCPhysReg > RegList)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isTargetAEABI() const
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
CCState - This class holds information needed while lowering arguments and return values.
MachineFunction & getMachineFunction() const
unsigned getFirstUnallocated(ArrayRef< MCPhysReg > Regs) const
getFirstUnallocated - Return the index of the first unallocated register in the set,...
MCRegister AllocateReg(MCPhysReg Reg)
AllocateReg - Attempt to allocate one register.
ArrayRef< MCPhysReg > AllocateRegBlock(ArrayRef< MCPhysReg > Regs, unsigned RegsRequired)
Attempt to allocate a block of RegsRequired consecutive registers.
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
uint64_t getStackSize() const
Returns the size of the currently allocated portion of the stack.
SmallVectorImpl< CCValAssign > & getPendingLocs()
void addLoc(const CCValAssign &V)
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getCustomMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP)
Wrapper class representing physical registers. Should be passed by value.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
Align getNonZeroOrigAlign() const
bool isInConsecutiveRegsLast() const
Align getNonZeroMemAlign() const
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.