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/Support/Alignment.h"
18 #include "llvm/Support/MachineValueType.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 IsInReg : 1;    ///< Passed in register
32     unsigned IsSRet : 1;     ///< Hidden struct-ret ptr
33     unsigned IsByVal : 1;    ///< Struct passed by value
34     unsigned IsNest : 1;     ///< Nested fn static chain
35     unsigned IsReturned : 1; ///< Always returned
36     unsigned IsSplit : 1;
37     unsigned IsInAlloca : 1;   ///< Passed with inalloca
38     unsigned IsSplitEnd : 1;   ///< Last part of a split
39     unsigned IsSwiftSelf : 1;  ///< Swift self parameter
40     unsigned IsSwiftError : 1; ///< Swift error parameter
41     unsigned IsCFGuardTarget : 1; ///< Control Flow Guard target
42     unsigned IsHva : 1;        ///< HVA field for
43     unsigned IsHvaStart : 1;   ///< HVA structure start
44     unsigned IsSecArgPass : 1; ///< Second argument
45     unsigned ByValAlign : 4;   ///< Log 2 of byval alignment
46     unsigned OrigAlign : 5;    ///< Log 2 of original alignment
47     unsigned IsInConsecutiveRegsLast : 1;
48     unsigned IsInConsecutiveRegs : 1;
49     unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
50     unsigned IsPointer : 1;
51 
52     unsigned ByValSize; ///< Byval struct size
53 
54     unsigned PointerAddrSpace; ///< Address space of pointer argument
55 
56   public:
57     ArgFlagsTy()
58         : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
59           IsReturned(0), IsSplit(0), IsInAlloca(0), IsSplitEnd(0),
60           IsSwiftSelf(0), IsSwiftError(0), IsCFGuardTarget(0), IsHva(0),
61           IsHvaStart(0), IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
62           IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
63           IsCopyElisionCandidate(0), IsPointer(0), ByValSize(0),
64           PointerAddrSpace(0) {
65       static_assert(sizeof(*this) == 3 * sizeof(unsigned), "flags are too big");
66     }
67 
68     bool isZExt() const { return IsZExt; }
69     void setZExt() { IsZExt = 1; }
70 
71     bool isSExt() const { return IsSExt; }
72     void setSExt() { IsSExt = 1; }
73 
74     bool isInReg() const { return IsInReg; }
75     void setInReg() { IsInReg = 1; }
76 
77     bool isSRet() const { return IsSRet; }
78     void setSRet() { IsSRet = 1; }
79 
80     bool isByVal() const { return IsByVal; }
81     void setByVal() { IsByVal = 1; }
82 
83     bool isInAlloca() const { return IsInAlloca; }
84     void setInAlloca() { IsInAlloca = 1; }
85 
86     bool isSwiftSelf() const { return IsSwiftSelf; }
87     void setSwiftSelf() { IsSwiftSelf = 1; }
88 
89     bool isSwiftError() const { return IsSwiftError; }
90     void setSwiftError() { IsSwiftError = 1; }
91 
92     bool isCFGuardTarget() const { return IsCFGuardTarget; }
93     void setCFGuardTarget() { IsCFGuardTarget = 1; }
94 
95     bool isHva() const { return IsHva; }
96     void setHva() { IsHva = 1; }
97 
98     bool isHvaStart() const { return IsHvaStart; }
99     void setHvaStart() { IsHvaStart = 1; }
100 
101     bool isSecArgPass() const { return IsSecArgPass; }
102     void setSecArgPass() { IsSecArgPass = 1; }
103 
104     bool isNest() const { return IsNest; }
105     void setNest() { IsNest = 1; }
106 
107     bool isReturned() const { return IsReturned; }
108     void setReturned() { IsReturned = 1; }
109 
110     bool isInConsecutiveRegs()  const { return IsInConsecutiveRegs; }
111     void setInConsecutiveRegs() { IsInConsecutiveRegs = 1; }
112 
113     bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
114     void setInConsecutiveRegsLast() { IsInConsecutiveRegsLast = 1; }
115 
116     bool isSplit()   const { return IsSplit; }
117     void setSplit()  { IsSplit = 1; }
118 
119     bool isSplitEnd()   const { return IsSplitEnd; }
120     void setSplitEnd()  { IsSplitEnd = 1; }
121 
122     bool isCopyElisionCandidate()  const { return IsCopyElisionCandidate; }
123     void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
124 
125     bool isPointer()  const { return IsPointer; }
126     void setPointer() { IsPointer = 1; }
127 
128     unsigned getByValAlign() const {
129       MaybeAlign A = decodeMaybeAlign(ByValAlign);
130       return A ? A->value() : 0;
131     }
132     void setByValAlign(Align A) {
133       ByValAlign = encode(A);
134       assert(getByValAlign() == A.value() && "bitfield overflow");
135     }
136 
137     unsigned getOrigAlign() const {
138       MaybeAlign A = decodeMaybeAlign(OrigAlign);
139       return A ? A->value() : 0;
140     }
141     void setOrigAlign(Align A) {
142       OrigAlign = encode(A);
143       assert(getOrigAlign() == A.value() && "bitfield overflow");
144     }
145 
146     unsigned getByValSize() const { return ByValSize; }
147     void setByValSize(unsigned S) { ByValSize = S; }
148 
149     unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
150     void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
151 };
152 
153   /// InputArg - This struct carries flags and type information about a
154   /// single incoming (formal) argument or incoming (from the perspective
155   /// of the caller) return value virtual register.
156   ///
157   struct InputArg {
158     ArgFlagsTy Flags;
159     MVT VT = MVT::Other;
160     EVT ArgVT;
161     bool Used = false;
162 
163     /// Index original Function's argument.
164     unsigned OrigArgIndex;
165     /// Sentinel value for implicit machine-level input arguments.
166     static const unsigned NoArgIndex = UINT_MAX;
167 
168     /// Offset in bytes of current input value relative to the beginning of
169     /// original argument. E.g. if argument was splitted into four 32 bit
170     /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
171     unsigned PartOffset;
172 
173     InputArg() = default;
174     InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
175              unsigned origIdx, unsigned partOffs)
176       : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
177       VT = vt.getSimpleVT();
178       ArgVT = argvt;
179     }
180 
181     bool isOrigArg() const {
182       return OrigArgIndex != NoArgIndex;
183     }
184 
185     unsigned getOrigArgIndex() const {
186       assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
187       return OrigArgIndex;
188     }
189   };
190 
191   /// OutputArg - This struct carries flags and a value for a
192   /// single outgoing (actual) argument or outgoing (from the perspective
193   /// of the caller) return value virtual register.
194   ///
195   struct OutputArg {
196     ArgFlagsTy Flags;
197     MVT VT;
198     EVT ArgVT;
199 
200     /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
201     bool IsFixed = false;
202 
203     /// Index original Function's argument.
204     unsigned OrigArgIndex;
205 
206     /// Offset in bytes of current output value relative to the beginning of
207     /// original argument. E.g. if argument was splitted into four 32 bit
208     /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
209     unsigned PartOffset;
210 
211     OutputArg() = default;
212     OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed,
213               unsigned origIdx, unsigned partOffs)
214       : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
215         PartOffset(partOffs) {
216       VT = vt.getSimpleVT();
217       ArgVT = argvt;
218     }
219   };
220 
221 } // end namespace ISD
222 } // end namespace llvm
223 
224 #endif // LLVM_CODEGEN_TARGETCALLINGCONV_H
225