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