1//===-- llvm/CodeGen/TargetCallingConv.h - Calling Convention ---*- 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 defines types for working with calling-convention information.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CODEGEN_TARGETCALLINGCONV_H
14#define LLVM_CODEGEN_TARGETCALLINGCONV_H
15
16#include "llvm/CodeGen/ValueTypes.h"
17#include "llvm/CodeGenTypes/MachineValueType.h"
18#include "llvm/Support/Alignment.h"
19#include "llvm/Support/MathExtras.h"
20#include <cassert>
21#include <climits>
22#include <cstdint>
23
24namespace llvm {
25namespace ISD {
26
27 struct ArgFlagsTy {
28 private:
29 unsigned IsZExt : 1; ///< Zero extended
30 unsigned IsSExt : 1; ///< Sign extended
31 unsigned IsInReg : 1; ///< Passed in register
32 unsigned IsSRet : 1; ///< Hidden struct-ret ptr
33 unsigned IsByVal : 1; ///< Struct passed by value
34 unsigned IsByRef : 1; ///< Passed in memory
35 unsigned IsNest : 1; ///< Nested fn static chain
36 unsigned IsReturned : 1; ///< Always returned
37 unsigned IsSplit : 1;
38 unsigned IsInAlloca : 1; ///< Passed with inalloca
39 unsigned IsPreallocated : 1; ///< ByVal without the copy
40 unsigned IsSplitEnd : 1; ///< Last part of a split
41 unsigned IsSwiftSelf : 1; ///< Swift self parameter
42 unsigned IsSwiftAsync : 1; ///< Swift async context parameter
43 unsigned IsSwiftError : 1; ///< Swift error parameter
44 unsigned IsCFGuardTarget : 1; ///< Control Flow Guard target
45 unsigned IsHva : 1; ///< HVA field for
46 unsigned IsHvaStart : 1; ///< HVA structure start
47 unsigned IsSecArgPass : 1; ///< Second argument
48 unsigned MemAlign : 4; ///< Log 2 of alignment when arg is passed in memory
49 ///< (including byval/byref). The max alignment is
50 ///< verified in IR verification.
51 unsigned OrigAlign : 5; ///< Log 2 of original alignment
52 unsigned IsInConsecutiveRegsLast : 1;
53 unsigned IsInConsecutiveRegs : 1;
54 unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
55 unsigned IsPointer : 1;
56
57 unsigned ByValOrByRefSize = 0; ///< Byval or byref struct size
58
59 unsigned PointerAddrSpace = 0; ///< Address space of pointer argument
60
61 public:
62 ArgFlagsTy()
63 : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsByRef(0),
64 IsNest(0), IsReturned(0), IsSplit(0), IsInAlloca(0),
65 IsPreallocated(0), IsSplitEnd(0), IsSwiftSelf(0), IsSwiftAsync(0),
66 IsSwiftError(0), IsCFGuardTarget(0), IsHva(0), IsHvaStart(0),
67 IsSecArgPass(0), MemAlign(0), OrigAlign(0),
68 IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
69 IsCopyElisionCandidate(0), IsPointer(0) {
70 static_assert(sizeof(*this) == 3 * sizeof(unsigned), "flags are too big");
71 }
72
73 bool isZExt() const { return IsZExt; }
74 void setZExt() { IsZExt = 1; }
75
76 bool isSExt() const { return IsSExt; }
77 void setSExt() { IsSExt = 1; }
78
79 bool isInReg() const { return IsInReg; }
80 void setInReg() { IsInReg = 1; }
81
82 bool isSRet() const { return IsSRet; }
83 void setSRet() { IsSRet = 1; }
84
85 bool isByVal() const { return IsByVal; }
86 void setByVal() { IsByVal = 1; }
87
88 bool isByRef() const { return IsByRef; }
89 void setByRef() { IsByRef = 1; }
90
91 bool isInAlloca() const { return IsInAlloca; }
92 void setInAlloca() { IsInAlloca = 1; }
93
94 bool isPreallocated() const { return IsPreallocated; }
95 void setPreallocated() { IsPreallocated = 1; }
96
97 bool isSwiftSelf() const { return IsSwiftSelf; }
98 void setSwiftSelf() { IsSwiftSelf = 1; }
99
100 bool isSwiftAsync() const { return IsSwiftAsync; }
101 void setSwiftAsync() { IsSwiftAsync = 1; }
102
103 bool isSwiftError() const { return IsSwiftError; }
104 void setSwiftError() { IsSwiftError = 1; }
105
106 bool isCFGuardTarget() const { return IsCFGuardTarget; }
107 void setCFGuardTarget() { IsCFGuardTarget = 1; }
108
109 bool isHva() const { return IsHva; }
110 void setHva() { IsHva = 1; }
111
112 bool isHvaStart() const { return IsHvaStart; }
113 void setHvaStart() { IsHvaStart = 1; }
114
115 bool isSecArgPass() const { return IsSecArgPass; }
116 void setSecArgPass() { IsSecArgPass = 1; }
117
118 bool isNest() const { return IsNest; }
119 void setNest() { IsNest = 1; }
120
121 bool isReturned() const { return IsReturned; }
122 void setReturned(bool V = true) { IsReturned = V; }
123
124 bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; }
125 void setInConsecutiveRegs(bool Flag = true) { IsInConsecutiveRegs = Flag; }
126
127 bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
128 void setInConsecutiveRegsLast(bool Flag = true) {
129 IsInConsecutiveRegsLast = Flag;
130 }
131
132 bool isSplit() const { return IsSplit; }
133 void setSplit() { IsSplit = 1; }
134
135 bool isSplitEnd() const { return IsSplitEnd; }
136 void setSplitEnd() { IsSplitEnd = 1; }
137
138 bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
139 void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
140
141 bool isPointer() const { return IsPointer; }
142 void setPointer() { IsPointer = 1; }
143
144 Align getNonZeroMemAlign() const {
145 return decodeMaybeAlign(Value: MemAlign).valueOrOne();
146 }
147
148 void setMemAlign(Align A) {
149 MemAlign = encode(A);
150 assert(getNonZeroMemAlign() == A && "bitfield overflow");
151 }
152
153 Align getNonZeroByValAlign() const {
154 assert(isByVal());
155 MaybeAlign A = decodeMaybeAlign(Value: MemAlign);
156 assert(A && "ByValAlign must be defined");
157 return *A;
158 }
159
160 Align getNonZeroOrigAlign() const {
161 return decodeMaybeAlign(Value: OrigAlign).valueOrOne();
162 }
163
164 void setOrigAlign(Align A) {
165 OrigAlign = encode(A);
166 assert(getNonZeroOrigAlign() == A && "bitfield overflow");
167 }
168
169 unsigned getByValSize() const {
170 assert(isByVal() && !isByRef());
171 return ByValOrByRefSize;
172 }
173 void setByValSize(unsigned S) {
174 assert(isByVal() && !isByRef());
175 ByValOrByRefSize = S;
176 }
177
178 unsigned getByRefSize() const {
179 assert(!isByVal() && isByRef());
180 return ByValOrByRefSize;
181 }
182 void setByRefSize(unsigned S) {
183 assert(!isByVal() && isByRef());
184 ByValOrByRefSize = S;
185 }
186
187 unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
188 void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
189};
190
191 /// InputArg - This struct carries flags and type information about a
192 /// single incoming (formal) argument or incoming (from the perspective
193 /// of the caller) return value virtual register.
194 ///
195 struct InputArg {
196 ArgFlagsTy Flags;
197 MVT VT = MVT::Other;
198 EVT ArgVT;
199 bool Used = false;
200
201 /// Index original Function's argument.
202 unsigned OrigArgIndex;
203 /// Sentinel value for implicit machine-level input arguments.
204 static const unsigned NoArgIndex = UINT_MAX;
205
206 /// Offset in bytes of current input value relative to the beginning of
207 /// original argument. E.g. if argument was splitted into four 32 bit
208 /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
209 unsigned PartOffset;
210
211 InputArg() = default;
212 InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
213 unsigned origIdx, unsigned partOffs)
214 : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
215 VT = vt.getSimpleVT();
216 ArgVT = argvt;
217 }
218
219 bool isOrigArg() const {
220 return OrigArgIndex != NoArgIndex;
221 }
222
223 unsigned getOrigArgIndex() const {
224 assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
225 return OrigArgIndex;
226 }
227 };
228
229 /// OutputArg - This struct carries flags and a value for a
230 /// single outgoing (actual) argument or outgoing (from the perspective
231 /// of the caller) return value virtual register.
232 ///
233 struct OutputArg {
234 ArgFlagsTy Flags;
235 MVT VT;
236 EVT ArgVT;
237
238 /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
239 bool IsFixed = false;
240
241 /// Index original Function's argument.
242 unsigned OrigArgIndex;
243
244 /// Offset in bytes of current output value relative to the beginning of
245 /// original argument. E.g. if argument was splitted into four 32 bit
246 /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
247 unsigned PartOffset;
248
249 OutputArg() = default;
250 OutputArg(ArgFlagsTy flags, MVT vt, EVT argvt, bool isfixed,
251 unsigned origIdx, unsigned partOffs)
252 : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
253 PartOffset(partOffs) {
254 VT = vt;
255 ArgVT = argvt;
256 }
257 };
258
259} // end namespace ISD
260} // end namespace llvm
261
262#endif // LLVM_CODEGEN_TARGETCALLINGCONV_H
263

source code of llvm/include/llvm/CodeGen/TargetCallingConv.h