blob: 7d138f5851713d3eff32bc9417502509ee75f965 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===-- llvm/CodeGen/TargetCallingConv.h - Calling Convention ---*- 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 defines types for working with calling-convention information.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CODEGEN_TARGETCALLINGCONV_H
15#define LLVM_CODEGEN_TARGETCALLINGCONV_H
16
17#include "llvm/CodeGen/ValueTypes.h"
18#include "llvm/Support/MachineValueType.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 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 IsHva : 1; ///< HVA field for
42 unsigned IsHvaStart : 1; ///< HVA structure start
43 unsigned IsSecArgPass : 1; ///< Second argument
44 unsigned ByValAlign : 4; ///< Log 2 of byval alignment
45 unsigned OrigAlign : 5; ///< Log 2 of original alignment
46 unsigned IsInConsecutiveRegsLast : 1;
47 unsigned IsInConsecutiveRegs : 1;
48 unsigned IsCopyElisionCandidate : 1; ///< Argument copy elision candidate
49
50 unsigned ByValSize; ///< Byval struct size
51
52 public:
53 ArgFlagsTy()
54 : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsNest(0),
55 IsReturned(0), IsSplit(0), IsInAlloca(0), IsSplitEnd(0),
56 IsSwiftSelf(0), IsSwiftError(0), IsHva(0), IsHvaStart(0),
57 IsSecArgPass(0), ByValAlign(0), OrigAlign(0),
58 IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
59 IsCopyElisionCandidate(0), ByValSize(0) {
60 static_assert(sizeof(*this) == 2 * sizeof(unsigned), "flags are too big");
61 }
62
63 bool isZExt() const { return IsZExt; }
64 void setZExt() { IsZExt = 1; }
65
66 bool isSExt() const { return IsSExt; }
67 void setSExt() { IsSExt = 1; }
68
69 bool isInReg() const { return IsInReg; }
70 void setInReg() { IsInReg = 1; }
71
72 bool isSRet() const { return IsSRet; }
73 void setSRet() { IsSRet = 1; }
74
75 bool isByVal() const { return IsByVal; }
76 void setByVal() { IsByVal = 1; }
77
78 bool isInAlloca() const { return IsInAlloca; }
79 void setInAlloca() { IsInAlloca = 1; }
80
81 bool isSwiftSelf() const { return IsSwiftSelf; }
82 void setSwiftSelf() { IsSwiftSelf = 1; }
83
84 bool isSwiftError() const { return IsSwiftError; }
85 void setSwiftError() { IsSwiftError = 1; }
86
87 bool isHva() const { return IsHva; }
88 void setHva() { IsHva = 1; }
89
90 bool isHvaStart() const { return IsHvaStart; }
91 void setHvaStart() { IsHvaStart = 1; }
92
93 bool isSecArgPass() const { return IsSecArgPass; }
94 void setSecArgPass() { IsSecArgPass = 1; }
95
96 bool isNest() const { return IsNest; }
97 void setNest() { IsNest = 1; }
98
99 bool isReturned() const { return IsReturned; }
100 void setReturned() { IsReturned = 1; }
101
102 bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; }
103 void setInConsecutiveRegs() { IsInConsecutiveRegs = 1; }
104
105 bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
106 void setInConsecutiveRegsLast() { IsInConsecutiveRegsLast = 1; }
107
108 bool isSplit() const { return IsSplit; }
109 void setSplit() { IsSplit = 1; }
110
111 bool isSplitEnd() const { return IsSplitEnd; }
112 void setSplitEnd() { IsSplitEnd = 1; }
113
114 bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
115 void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
116
117 unsigned getByValAlign() const { return (1U << ByValAlign) / 2; }
118 void setByValAlign(unsigned A) {
119 ByValAlign = Log2_32(A) + 1;
120 assert(getByValAlign() == A && "bitfield overflow");
121 }
122
123 unsigned getOrigAlign() const { return (1U << OrigAlign) / 2; }
124 void setOrigAlign(unsigned A) {
125 OrigAlign = Log2_32(A) + 1;
126 assert(getOrigAlign() == A && "bitfield overflow");
127 }
128
129 unsigned getByValSize() const { return ByValSize; }
130 void setByValSize(unsigned S) { ByValSize = S; }
131 };
132
133 /// InputArg - This struct carries flags and type information about a
134 /// single incoming (formal) argument or incoming (from the perspective
135 /// of the caller) return value virtual register.
136 ///
137 struct InputArg {
138 ArgFlagsTy Flags;
139 MVT VT = MVT::Other;
140 EVT ArgVT;
141 bool Used = false;
142
143 /// Index original Function's argument.
144 unsigned OrigArgIndex;
145 /// Sentinel value for implicit machine-level input arguments.
146 static const unsigned NoArgIndex = UINT_MAX;
147
148 /// Offset in bytes of current input value relative to the beginning of
149 /// original argument. E.g. if argument was splitted into four 32 bit
150 /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
151 unsigned PartOffset;
152
153 InputArg() = default;
154 InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
155 unsigned origIdx, unsigned partOffs)
156 : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
157 VT = vt.getSimpleVT();
158 ArgVT = argvt;
159 }
160
161 bool isOrigArg() const {
162 return OrigArgIndex != NoArgIndex;
163 }
164
165 unsigned getOrigArgIndex() const {
166 assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
167 return OrigArgIndex;
168 }
169 };
170
171 /// OutputArg - This struct carries flags and a value for a
172 /// single outgoing (actual) argument or outgoing (from the perspective
173 /// of the caller) return value virtual register.
174 ///
175 struct OutputArg {
176 ArgFlagsTy Flags;
177 MVT VT;
178 EVT ArgVT;
179
180 /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
181 bool IsFixed = false;
182
183 /// Index original Function's argument.
184 unsigned OrigArgIndex;
185
186 /// Offset in bytes of current output value relative to the beginning of
187 /// original argument. E.g. if argument was splitted into four 32 bit
188 /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
189 unsigned PartOffset;
190
191 OutputArg() = default;
192 OutputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool isfixed,
193 unsigned origIdx, unsigned partOffs)
194 : Flags(flags), IsFixed(isfixed), OrigArgIndex(origIdx),
195 PartOffset(partOffs) {
196 VT = vt.getSimpleVT();
197 ArgVT = argvt;
198 }
199 };
200
201} // end namespace ISD
202} // end namespace llvm
203
204#endif // LLVM_CODEGEN_TARGETCALLINGCONV_H