1 //===-- 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 
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 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:
ArgFlagsTyArgFlagsTy53     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 
isZExtArgFlagsTy63     bool isZExt() const { return IsZExt; }
setZExtArgFlagsTy64     void setZExt() { IsZExt = 1; }
65 
isSExtArgFlagsTy66     bool isSExt() const { return IsSExt; }
setSExtArgFlagsTy67     void setSExt() { IsSExt = 1; }
68 
isInRegArgFlagsTy69     bool isInReg() const { return IsInReg; }
setInRegArgFlagsTy70     void setInReg() { IsInReg = 1; }
71 
isSRetArgFlagsTy72     bool isSRet() const { return IsSRet; }
setSRetArgFlagsTy73     void setSRet() { IsSRet = 1; }
74 
isByValArgFlagsTy75     bool isByVal() const { return IsByVal; }
setByValArgFlagsTy76     void setByVal() { IsByVal = 1; }
77 
isInAllocaArgFlagsTy78     bool isInAlloca() const { return IsInAlloca; }
setInAllocaArgFlagsTy79     void setInAlloca() { IsInAlloca = 1; }
80 
isSwiftSelfArgFlagsTy81     bool isSwiftSelf() const { return IsSwiftSelf; }
setSwiftSelfArgFlagsTy82     void setSwiftSelf() { IsSwiftSelf = 1; }
83 
isSwiftErrorArgFlagsTy84     bool isSwiftError() const { return IsSwiftError; }
setSwiftErrorArgFlagsTy85     void setSwiftError() { IsSwiftError = 1; }
86 
isHvaArgFlagsTy87     bool isHva() const { return IsHva; }
setHvaArgFlagsTy88     void setHva() { IsHva = 1; }
89 
isHvaStartArgFlagsTy90     bool isHvaStart() const { return IsHvaStart; }
setHvaStartArgFlagsTy91     void setHvaStart() { IsHvaStart = 1; }
92 
isSecArgPassArgFlagsTy93     bool isSecArgPass() const { return IsSecArgPass; }
setSecArgPassArgFlagsTy94     void setSecArgPass() { IsSecArgPass = 1; }
95 
isNestArgFlagsTy96     bool isNest() const { return IsNest; }
setNestArgFlagsTy97     void setNest() { IsNest = 1; }
98 
isReturnedArgFlagsTy99     bool isReturned() const { return IsReturned; }
setReturnedArgFlagsTy100     void setReturned() { IsReturned = 1; }
101 
isInConsecutiveRegsArgFlagsTy102     bool isInConsecutiveRegs()  const { return IsInConsecutiveRegs; }
setInConsecutiveRegsArgFlagsTy103     void setInConsecutiveRegs() { IsInConsecutiveRegs = 1; }
104 
isInConsecutiveRegsLastArgFlagsTy105     bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
setInConsecutiveRegsLastArgFlagsTy106     void setInConsecutiveRegsLast() { IsInConsecutiveRegsLast = 1; }
107 
isSplitArgFlagsTy108     bool isSplit()   const { return IsSplit; }
setSplitArgFlagsTy109     void setSplit()  { IsSplit = 1; }
110 
isSplitEndArgFlagsTy111     bool isSplitEnd()   const { return IsSplitEnd; }
setSplitEndArgFlagsTy112     void setSplitEnd()  { IsSplitEnd = 1; }
113 
isCopyElisionCandidateArgFlagsTy114     bool isCopyElisionCandidate()  const { return IsCopyElisionCandidate; }
setCopyElisionCandidateArgFlagsTy115     void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
116 
getByValAlignArgFlagsTy117     unsigned getByValAlign() const { return (1U << ByValAlign) / 2; }
setByValAlignArgFlagsTy118     void setByValAlign(unsigned A) {
119       ByValAlign = Log2_32(A) + 1;
120       assert(getByValAlign() == A && "bitfield overflow");
121     }
122 
getOrigAlignArgFlagsTy123     unsigned getOrigAlign() const { return (1U << OrigAlign) / 2; }
setOrigAlignArgFlagsTy124     void setOrigAlign(unsigned A) {
125       OrigAlign = Log2_32(A) + 1;
126       assert(getOrigAlign() == A && "bitfield overflow");
127     }
128 
getByValSizeArgFlagsTy129     unsigned getByValSize() const { return ByValSize; }
setByValSizeArgFlagsTy130     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;
InputArgInputArg154     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 
isOrigArgInputArg161     bool isOrigArg() const {
162       return OrigArgIndex != NoArgIndex;
163     }
164 
getOrigArgIndexInputArg165     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;
OutputArgOutputArg192     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
205