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