LLVM  8.0.1
X86CallingConv.cpp
Go to the documentation of this file.
1 //=== X86CallingConv.cpp - X86 Custom Calling Convention Impl -*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the implementation of custom routines for the X86
11 // Calling Convention that aren't done by tablegen.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "X86Subtarget.h"
18 #include "llvm/IR/CallingConv.h"
19 
20 namespace llvm {
21 
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,
28  X86::ESI};
29 
30  // The vector will save all the available registers for allocation.
31  SmallVector<unsigned, 5> AvailableRegs;
32 
33  // searching for the available registers.
34  for (auto Reg : RegList) {
35  if (!State.isAllocated(Reg))
36  AvailableRegs.push_back(Reg);
37  }
38 
39  const size_t RequiredGprsUponSplit = 2;
40  if (AvailableRegs.size() < RequiredGprsUponSplit)
41  return false; // Not enough free registers - continue the search.
42 
43  // Allocating the available registers.
44  for (unsigned I = 0; I < RequiredGprsUponSplit; I++) {
45 
46  // Marking the register as located.
47  unsigned Reg = State.AllocateReg(AvailableRegs[I]);
48 
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");
52 
53  // Assign the value to the allocated register
54  State.addLoc(CCValAssign::getCustomReg(ValNo, ValVT, Reg, LocVT, LocInfo));
55  }
56 
57  // Successful in allocating regsiters - stop scanning next rules.
58  return true;
59 }
60 
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));
66  }
67 
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));
72  }
73 
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));
77 }
78 
80  static const MCPhysReg RegListGPR[] = {X86::RCX, X86::RDX, X86::R8, X86::R9};
81  return makeArrayRef(std::begin(RegListGPR), std::end(RegListGPR));
82 }
83 
84 static bool CC_X86_VectorCallAssignRegister(unsigned &ValNo, MVT &ValVT,
85  MVT &LocVT,
86  CCValAssign::LocInfo &LocInfo,
87  ISD::ArgFlagsTy &ArgFlags,
88  CCState &State) {
89 
91  bool Is64bit = static_cast<const X86Subtarget &>(
93  .is64Bit();
94 
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");
100  State.addLoc(
101  CCValAssign::getReg(ValNo, ValVT, AssigedReg, LocVT, LocInfo));
102  return true;
103  }
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));
107  return true;
108  }
109  }
110 
111  llvm_unreachable("Clang should ensure that hva marked vectors will have "
112  "an available register.");
113  return false;
114 }
115 
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,
123  ArgFlags, State);
124  return true;
125  }
126 
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));
138  }
139 
140  return false;
141  }
142 
143  if (!ArgFlags.isHva() || ArgFlags.isHvaStart()) {
144  // Assign shadow GPR register.
146 
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);
155 
156  if (!ArgFlags.isHva()) {
157  State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
158  return true; // Allocated a register - Stop the search.
159  }
160  }
161  }
162 
163  // If this is an HVA - Stop the search,
164  // otherwise continue the search.
165  return ArgFlags.isHva();
166 }
167 
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,
175  ArgFlags, State);
176  return true;
177  }
178 
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))) {
184  return false;
185  }
186 
187  if (ArgFlags.isHva())
188  return true; // If this is an HVA - Stop the search.
189 
190  // Assign XMM register.
191  if (unsigned Reg = State.AllocateReg(CC_X86_VectorCallGetSSEs(ValVT))) {
192  State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo));
193  return true;
194  }
195 
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()) {
200  LocVT = MVT::i32;
201  LocInfo = CCValAssign::Indirect;
202  ArgFlags.setInReg();
203  }
204 
205  return false; // No register was assigned - Continue the search.
206 }
207 
208 } // End llvm namespace
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:259
static CCValAssign getCustomReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:250
static bool CC_X86_VectorCallAssignRegister(unsigned &ValNo, MVT &ValVT, MVT &LocVT, CCValAssign::LocInfo &LocInfo, ISD::ArgFlagsTy &ArgFlags, CCState &State)
This class represents lattice values for constants.
Definition: AllocatorList.h:24
bool isVector() const
Return true if this is a vector value type.
bool isAllocated(unsigned Reg) const
isAllocated - Return true if the specified register (or an alias) is allocated.
bool is256BitVector() const
Return true if this is a 256-bit vector type.
unsigned Reg
MachineFunction & getMachineFunction() const
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
void addLoc(const CCValAssign &V)
static ArrayRef< MCPhysReg > CC_X86_64_VectorCallGetGPRs()
unsigned getSizeInBits() const
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...
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
static CCValAssign getReg(unsigned ValNo, MVT ValVT, unsigned RegNo, MVT LocVT, LocInfo HTP)
Machine Value Type.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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...
static bool is64Bit(const char *name)
size_t size() const
Definition: SmallVector.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isFloatingPoint() const
Return true if this is a FP or a vector FP type.
CCState - This class holds information needed while lowering arguments and return values...
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
#define I(x, y, z)
Definition: MD5.cpp:58
bool is512BitVector() const
Return true if this is a 512-bit vector type.
bool IsShadowAllocatedReg(unsigned Reg) const
A shadow allocated register is a register that was allocated but wasn&#39;t added to the location list (L...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static ArrayRef< MCPhysReg > CC_X86_VectorCallGetSSEs(const MVT &ValVT)
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...
unsigned AllocateReg(unsigned Reg)
AllocateReg - Attempt to allocate one register.
unsigned AllocateStack(unsigned Size, unsigned Align)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.