LLVM: lib/Target/X86/X86CallingConv.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
19
20using namespace llvm;
21
22
23
24
25
27 MVT &LocVT,
31
32
33 static const MCPhysReg RegList[] = {X86::EAX, X86::ECX, X86::EDX, X86::EDI,
34 X86::ESI};
35
36
38
39
40 for (auto Reg : RegList) {
41 if (!State.isAllocated(Reg))
43 }
44
45 const size_t RequiredGprsUponSplit = 2;
46 if (AvailableRegs.size() < RequiredGprsUponSplit)
47 return false;
48
49
50 for (unsigned I = 0; I < RequiredGprsUponSplit; I++) {
51
52
54
55
56
57 assert(Reg && "Expecting a register will be available");
58
59
61 }
62
63
64 return true;
65}
66
69 static const MCPhysReg RegListZMM[] = {X86::ZMM0, X86::ZMM1, X86::ZMM2,
70 X86::ZMM3, X86::ZMM4, X86::ZMM5};
71 return RegListZMM;
72 }
73
75 static const MCPhysReg RegListYMM[] = {X86::YMM0, X86::YMM1, X86::YMM2,
76 X86::YMM3, X86::YMM4, X86::YMM5};
77 return RegListYMM;
78 }
79
80 static const MCPhysReg RegListXMM[] = {X86::XMM0, X86::XMM1, X86::XMM2,
81 X86::XMM3, X86::XMM4, X86::XMM5};
82 return RegListXMM;
83}
84
86 static const MCPhysReg RegListGPR[] = {X86::RCX, X86::RDX, X86::R8, X86::R9};
87 return RegListGPR;
88}
89
91 MVT &LocVT,
95
97 bool Is64bit = static_cast<const X86Subtarget &>(
98 State.getMachineFunction().getSubtarget())
99 .is64Bit();
100
101 for (auto Reg : RegList) {
102
103 if (!State.isAllocated(Reg)) {
105 assert(AssigedReg == Reg && "Expecting a valid register allocation");
106 State.addLoc(
108 return true;
109 }
110
111 if (Is64bit && State.IsShadowAllocatedReg(Reg)) {
113 return true;
114 }
115 }
116
117 llvm_unreachable("Clang should ensure that hva marked vectors will have "
118 "an available register.");
119 return false;
120}
121
122
123
124
125
126
127
131
133 if (ArgFlags.isHva())
135 ArgFlags, State);
136 return true;
137 }
138
139
140
141
144
145
146
147 if (State.isAllocated(X86::R9)) {
148
150 }
151
152 return false;
153 }
154
156
158
159
161
162
163
164
166 State.getMachineFunction().getSubtarget().getRegisterInfo();
167 if (TRI->regsOverlap(Reg, X86::XMM4) ||
168 TRI->regsOverlap(Reg, X86::XMM5))
169 State.AllocateStack(8, Align(8));
170
171 if (!ArgFlags.isHva()) {
173 return true;
174 }
175 }
176 }
177
178
179
180 return ArgFlags.isHva();
181}
182
183
184
185
186
187
191
193 if (ArgFlags.isHva())
195 ArgFlags, State);
196 return true;
197 }
198
199
200
201
204 return false;
205 }
206
207 if (ArgFlags.isHva())
208 return true;
209
210
213 return true;
214 }
215
216
217
218
220 LocVT = MVT::i32;
223 }
224
225 return false;
226}
227
231 llvm_unreachable("The AnyReg calling convention is only supported by the "
232 "stackmap and patchpoint intrinsics.");
233
234 return false;
235}
236
240
241
242 static const MCPhysReg RegList[] = {X86::EAX, X86::EDX, X86::ECX};
243 static const unsigned NumRegs = std::size(RegList);
244
246
247
248
249
250
251 if (ArgFlags.isSplit() || !PendingMembers.empty()) {
255 return true;
256 }
257
258
259
260 if (PendingMembers.empty()) {
261 if (MCRegister Reg = State.AllocateReg(RegList)) {
263 return true;
264 }
265 return false;
266 }
267
269
270
271
272
273
274
275
276
277 unsigned FirstFree = State.getFirstUnallocated(RegList);
278 bool UseRegs = PendingMembers.size() <= std::min(2U, NumRegs - FirstFree);
279
280 for (auto &It : PendingMembers) {
281 if (UseRegs)
282 It.convertToReg(State.AllocateReg(RegList[FirstFree++]));
283 else
284 It.convertToMem(State.AllocateStack(4, Align(4)));
285 State.addLoc(It);
286 }
287
288 PendingMembers.clear();
289
290 return true;
291}
292
293
294
295
296
303 unsigned SlotSize = Is64Bit ? 8 : 4;
305 if (ArgCount == 1 && ValNo == 0) {
306
307
308 Offset = State.AllocateStack(5 * SlotSize, Align(4));
309 } else if (ArgCount == 2 && ValNo == 0) {
310
311
312
314 } else if (ArgCount == 2 && ValNo == 1) {
315
316
317
319 (void)State.AllocateStack(6 * SlotSize, Align(4));
320 } else {
322 }
323
324
325
326 if (Is64Bit && ArgCount == 2)
328
330 return true;
331}
332
336 if (LocVT != MVT::i64) {
337 LocVT = MVT::i64;
339 }
340 return false;
341}
342
343
344
345
349 assert(ValVT == MVT::i64 && "Should have i64 parts");
353
355 return true;
356
357 unsigned NumRegs = PendingMembers.size();
358 assert(NumRegs == 2 && "Should have two parts");
359
360 static const MCPhysReg Regs[] = {X86::RDI, X86::RSI, X86::RDX,
361 X86::RCX, X86::R8, X86::R9};
363 if (!Allocated.empty()) {
364 PendingMembers[0].convertToReg(Allocated[0]);
365 PendingMembers[1].convertToReg(Allocated[1]);
366 } else {
367 int64_t Offset = State.AllocateStack(16, Align(16));
368 PendingMembers[0].convertToMem(Offset);
369 PendingMembers[1].convertToMem(Offset + 8);
370 }
371 State.addLoc(PendingMembers[0]);
372 State.addLoc(PendingMembers[1]);
373 PendingMembers.clear();
374 return true;
375}
376
377
378
379
380
384 assert(ValVT == MVT::i32 && "Should have i32 parts");
388
390 return true;
391
392 assert(PendingMembers.size() == 4 && "Should have four parts");
393
394 int64_t Offset = State.AllocateStack(16, Align(16));
395 PendingMembers[0].convertToMem(Offset);
396 PendingMembers[1].convertToMem(Offset + 4);
397 PendingMembers[2].convertToMem(Offset + 8);
398 PendingMembers[3].convertToMem(Offset + 12);
399
400 State.addLoc(PendingMembers[0]);
401 State.addLoc(PendingMembers[1]);
402 State.addLoc(PendingMembers[2]);
403 State.addLoc(PendingMembers[3]);
404 PendingMembers.clear();
405 return true;
406}
407
408
409#include "X86GenCallingConv.inc"
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Module.h This file contains the declarations for the Module class.
Register const TargetRegisterInfo * TRI
This file defines the SmallVector class.
static bool CC_X86_AnyReg_Error(unsigned &, MVT &, MVT &, CCValAssign::LocInfo &, ISD::ArgFlagsTy &, CCState &)
Definition X86CallingConv.cpp:228
static bool CC_X86_VectorCallAssignRegister(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
Definition X86CallingConv.cpp:90
static bool CC_X86_32_MCUInReg(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
Definition X86CallingConv.cpp:237
static bool CC_X86_32_RegCall_Assign2Regs(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
When regcall calling convention compiled to 32 bit arch, special treatment is required for 64 bit mas...
Definition X86CallingConv.cpp:26
static bool CC_X86_64_I128(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
Special handling for i128: Either allocate the value to two consecutive i64 registers,...
Definition X86CallingConv.cpp:346
static ArrayRef< MCPhysReg > CC_X86_VectorCallGetSSEs(const MVT &ValVT)
Definition X86CallingConv.cpp:67
static bool CC_X86_Intr(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
X86 interrupt handlers can only take one or two stack arguments, but if there are two arguments,...
Definition X86CallingConv.cpp:297
static ArrayRef< MCPhysReg > CC_X86_64_VectorCallGetGPRs()
Definition X86CallingConv.cpp:85
static bool CC_X86_64_VectorCall(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
Vectorcall calling convention has special handling for vector types or HVA for 64 bit arch.
Definition X86CallingConv.cpp:128
static bool CC_X86_32_I128_FP128(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
Special handling for i128 and fp128: on x86-32, i128 and fp128 get legalized as four i32s,...
Definition X86CallingConv.cpp:381
static bool CC_X86_32_VectorCall(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
Vectorcall calling convention has special handling for vector types or HVA for 32 bit arch.
Definition X86CallingConv.cpp:188
static bool CC_X86_64_Pointer(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
Definition X86CallingConv.cpp:333
static bool is64Bit(const char *name)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
CCState - This class holds information needed while lowering arguments and return values.
static CCValAssign getPending(unsigned ValNo, MVT ValVT, MVT LocVT, LocInfo HTP, unsigned ExtraInfo=0)
static CCValAssign getReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP, bool IsCustom=false)
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, MCRegister Reg, MVT LocVT, LocInfo HTP)
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
Wrapper class representing physical registers. Should be passed by value.
bool isVector() const
Return true if this is a vector value type.
bool is512BitVector() const
Return true if this is a 512-bit vector type.
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#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.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
This struct is a compact representation of a valid (non-zero power of two) alignment.
bool isSecArgPass() const
bool isInConsecutiveRegsLast() const