1 //=== X86CallingConv.cpp - X86 Custom Calling Convention Impl -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the implementation of custom routines for the X86
11 // Calling Convention that aren't done by tablegen.
13 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/X86MCTargetDesc.h"
16 #include "X86Subtarget.h"
17 #include "llvm/CodeGen/CallingConvLower.h"
18 #include "llvm/IR/CallingConv.h"
22 bool CC_X86_32_RegCall_Assign2Regs(unsigned &ValNo
, MVT
&ValVT
, MVT
&LocVT
,
23 CCValAssign::LocInfo
&LocInfo
,
24 ISD::ArgFlagsTy
&ArgFlags
, CCState
&State
) {
25 // List of GPR registers that are available to store values in regcall
26 // calling convention.
27 static const MCPhysReg RegList
[] = {X86::EAX
, X86::ECX
, X86::EDX
, X86::EDI
,
30 // The vector will save all the available registers for allocation.
31 SmallVector
<unsigned, 5> AvailableRegs
;
33 // searching for the available registers.
34 for (auto Reg
: RegList
) {
35 if (!State
.isAllocated(Reg
))
36 AvailableRegs
.push_back(Reg
);
39 const size_t RequiredGprsUponSplit
= 2;
40 if (AvailableRegs
.size() < RequiredGprsUponSplit
)
41 return false; // Not enough free registers - continue the search.
43 // Allocating the available registers.
44 for (unsigned I
= 0; I
< RequiredGprsUponSplit
; I
++) {
46 // Marking the register as located.
47 unsigned Reg
= State
.AllocateReg(AvailableRegs
[I
]);
49 // Since we previously made sure that 2 registers are available
50 // we expect that a real register number will be returned.
51 assert(Reg
&& "Expecting a register will be available");
53 // Assign the value to the allocated register
54 State
.addLoc(CCValAssign::getCustomReg(ValNo
, ValVT
, Reg
, LocVT
, LocInfo
));
57 // Successful in allocating regsiters - stop scanning next rules.
61 static ArrayRef
<MCPhysReg
> CC_X86_VectorCallGetSSEs(const MVT
&ValVT
) {
62 if (ValVT
.is512BitVector()) {
63 static const MCPhysReg RegListZMM
[] = {X86::ZMM0
, X86::ZMM1
, X86::ZMM2
,
64 X86::ZMM3
, X86::ZMM4
, X86::ZMM5
};
65 return makeArrayRef(std::begin(RegListZMM
), std::end(RegListZMM
));
68 if (ValVT
.is256BitVector()) {
69 static const MCPhysReg RegListYMM
[] = {X86::YMM0
, X86::YMM1
, X86::YMM2
,
70 X86::YMM3
, X86::YMM4
, X86::YMM5
};
71 return makeArrayRef(std::begin(RegListYMM
), std::end(RegListYMM
));
74 static const MCPhysReg RegListXMM
[] = {X86::XMM0
, X86::XMM1
, X86::XMM2
,
75 X86::XMM3
, X86::XMM4
, X86::XMM5
};
76 return makeArrayRef(std::begin(RegListXMM
), std::end(RegListXMM
));
79 static ArrayRef
<MCPhysReg
> CC_X86_64_VectorCallGetGPRs() {
80 static const MCPhysReg RegListGPR
[] = {X86::RCX
, X86::RDX
, X86::R8
, X86::R9
};
81 return makeArrayRef(std::begin(RegListGPR
), std::end(RegListGPR
));
84 static bool CC_X86_VectorCallAssignRegister(unsigned &ValNo
, MVT
&ValVT
,
86 CCValAssign::LocInfo
&LocInfo
,
87 ISD::ArgFlagsTy
&ArgFlags
,
90 ArrayRef
<MCPhysReg
> RegList
= CC_X86_VectorCallGetSSEs(ValVT
);
91 bool Is64bit
= static_cast<const X86Subtarget
&>(
92 State
.getMachineFunction().getSubtarget())
95 for (auto Reg
: RegList
) {
96 // If the register is not marked as allocated - assign to it.
97 if (!State
.isAllocated(Reg
)) {
98 unsigned AssigedReg
= State
.AllocateReg(Reg
);
99 assert(AssigedReg
== Reg
&& "Expecting a valid register allocation");
101 CCValAssign::getReg(ValNo
, ValVT
, AssigedReg
, LocVT
, LocInfo
));
104 // If the register is marked as shadow allocated - assign to it.
105 if (Is64bit
&& State
.IsShadowAllocatedReg(Reg
)) {
106 State
.addLoc(CCValAssign::getReg(ValNo
, ValVT
, Reg
, LocVT
, LocInfo
));
111 llvm_unreachable("Clang should ensure that hva marked vectors will have "
112 "an available register.");
116 bool CC_X86_64_VectorCall(unsigned &ValNo
, MVT
&ValVT
, MVT
&LocVT
,
117 CCValAssign::LocInfo
&LocInfo
,
118 ISD::ArgFlagsTy
&ArgFlags
, CCState
&State
) {
119 // On the second pass, go through the HVAs only.
120 if (ArgFlags
.isSecArgPass()) {
121 if (ArgFlags
.isHva())
122 return CC_X86_VectorCallAssignRegister(ValNo
, ValVT
, LocVT
, LocInfo
,
127 // Process only vector types as defined by vectorcall spec:
128 // "A vector type is either a floating-point type, for example,
129 // a float or double, or an SIMD vector type, for example, __m128 or __m256".
130 if (!(ValVT
.isFloatingPoint() ||
131 (ValVT
.isVector() && ValVT
.getSizeInBits() >= 128))) {
132 // If R9 was already assigned it means that we are after the fourth element
133 // and because this is not an HVA / Vector type, we need to allocate
134 // shadow XMM register.
135 if (State
.isAllocated(X86::R9
)) {
136 // Assign shadow XMM register.
137 (void)State
.AllocateReg(CC_X86_VectorCallGetSSEs(ValVT
));
143 if (!ArgFlags
.isHva() || ArgFlags
.isHvaStart()) {
144 // Assign shadow GPR register.
145 (void)State
.AllocateReg(CC_X86_64_VectorCallGetGPRs());
147 // Assign XMM register - (shadow for HVA and non-shadow for non HVA).
148 if (unsigned Reg
= State
.AllocateReg(CC_X86_VectorCallGetSSEs(ValVT
))) {
149 // In Vectorcall Calling convention, additional shadow stack can be
150 // created on top of the basic 32 bytes of win64.
151 // It can happen if the fifth or sixth argument is vector type or HVA.
152 // At that case for each argument a shadow stack of 8 bytes is allocated.
153 if (Reg
== X86::XMM4
|| Reg
== X86::XMM5
)
154 State
.AllocateStack(8, 8);
156 if (!ArgFlags
.isHva()) {
157 State
.addLoc(CCValAssign::getReg(ValNo
, ValVT
, Reg
, LocVT
, LocInfo
));
158 return true; // Allocated a register - Stop the search.
163 // If this is an HVA - Stop the search,
164 // otherwise continue the search.
165 return ArgFlags
.isHva();
168 bool CC_X86_32_VectorCall(unsigned &ValNo
, MVT
&ValVT
, MVT
&LocVT
,
169 CCValAssign::LocInfo
&LocInfo
,
170 ISD::ArgFlagsTy
&ArgFlags
, CCState
&State
) {
171 // On the second pass, go through the HVAs only.
172 if (ArgFlags
.isSecArgPass()) {
173 if (ArgFlags
.isHva())
174 return CC_X86_VectorCallAssignRegister(ValNo
, ValVT
, LocVT
, LocInfo
,
179 // Process only vector types as defined by vectorcall spec:
180 // "A vector type is either a floating point type, for example,
181 // a float or double, or an SIMD vector type, for example, __m128 or __m256".
182 if (!(ValVT
.isFloatingPoint() ||
183 (ValVT
.isVector() && ValVT
.getSizeInBits() >= 128))) {
187 if (ArgFlags
.isHva())
188 return true; // If this is an HVA - Stop the search.
190 // Assign XMM register.
191 if (unsigned Reg
= State
.AllocateReg(CC_X86_VectorCallGetSSEs(ValVT
))) {
192 State
.addLoc(CCValAssign::getReg(ValNo
, ValVT
, Reg
, LocVT
, LocInfo
));
196 // In case we did not find an available XMM register for a vector -
197 // pass it indirectly.
198 // It is similar to CCPassIndirect, with the addition of inreg.
199 if (!ValVT
.isFloatingPoint()) {
201 LocInfo
= CCValAssign::Indirect
;
205 return false; // No register was assigned - Continue the search.
208 } // End llvm namespace