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: ArgFlagsTyArgFlagsTy57 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 isZExtArgFlagsTy68 bool isZExt() const { return IsZExt; } setZExtArgFlagsTy69 void setZExt() { IsZExt = 1; } 70 isSExtArgFlagsTy71 bool isSExt() const { return IsSExt; } setSExtArgFlagsTy72 void setSExt() { IsSExt = 1; } 73 isInRegArgFlagsTy74 bool isInReg() const { return IsInReg; } setInRegArgFlagsTy75 void setInReg() { IsInReg = 1; } 76 isSRetArgFlagsTy77 bool isSRet() const { return IsSRet; } setSRetArgFlagsTy78 void setSRet() { IsSRet = 1; } 79 isByValArgFlagsTy80 bool isByVal() const { return IsByVal; } setByValArgFlagsTy81 void setByVal() { IsByVal = 1; } 82 isInAllocaArgFlagsTy83 bool isInAlloca() const { return IsInAlloca; } setInAllocaArgFlagsTy84 void setInAlloca() { IsInAlloca = 1; } 85 isSwiftSelfArgFlagsTy86 bool isSwiftSelf() const { return IsSwiftSelf; } setSwiftSelfArgFlagsTy87 void setSwiftSelf() { IsSwiftSelf = 1; } 88 isSwiftErrorArgFlagsTy89 bool isSwiftError() const { return IsSwiftError; } setSwiftErrorArgFlagsTy90 void setSwiftError() { IsSwiftError = 1; } 91 isCFGuardTargetArgFlagsTy92 bool isCFGuardTarget() const { return IsCFGuardTarget; } setCFGuardTargetArgFlagsTy93 void setCFGuardTarget() { IsCFGuardTarget = 1; } 94 isHvaArgFlagsTy95 bool isHva() const { return IsHva; } setHvaArgFlagsTy96 void setHva() { IsHva = 1; } 97 isHvaStartArgFlagsTy98 bool isHvaStart() const { return IsHvaStart; } setHvaStartArgFlagsTy99 void setHvaStart() { IsHvaStart = 1; } 100 isSecArgPassArgFlagsTy101 bool isSecArgPass() const { return IsSecArgPass; } setSecArgPassArgFlagsTy102 void setSecArgPass() { IsSecArgPass = 1; } 103 isNestArgFlagsTy104 bool isNest() const { return IsNest; } setNestArgFlagsTy105 void setNest() { IsNest = 1; } 106 isReturnedArgFlagsTy107 bool isReturned() const { return IsReturned; } setReturnedArgFlagsTy108 void setReturned() { IsReturned = 1; } 109 isInConsecutiveRegsArgFlagsTy110 bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; } setInConsecutiveRegsArgFlagsTy111 void setInConsecutiveRegs() { IsInConsecutiveRegs = 1; } 112 isInConsecutiveRegsLastArgFlagsTy113 bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; } setInConsecutiveRegsLastArgFlagsTy114 void setInConsecutiveRegsLast() { IsInConsecutiveRegsLast = 1; } 115 isSplitArgFlagsTy116 bool isSplit() const { return IsSplit; } setSplitArgFlagsTy117 void setSplit() { IsSplit = 1; } 118 isSplitEndArgFlagsTy119 bool isSplitEnd() const { return IsSplitEnd; } setSplitEndArgFlagsTy120 void setSplitEnd() { IsSplitEnd = 1; } 121 isCopyElisionCandidateArgFlagsTy122 bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; } setCopyElisionCandidateArgFlagsTy123 void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; } 124 isPointerArgFlagsTy125 bool isPointer() const { return IsPointer; } setPointerArgFlagsTy126 void setPointer() { IsPointer = 1; } 127 getByValAlignArgFlagsTy128 unsigned getByValAlign() const { 129 MaybeAlign A = decodeMaybeAlign(ByValAlign); 130 return A ? A->value() : 0; 131 } setByValAlignArgFlagsTy132 void setByValAlign(Align A) { 133 ByValAlign = encode(A); 134 assert(getByValAlign() == A.value() && "bitfield overflow"); 135 } 136 getOrigAlignArgFlagsTy137 unsigned getOrigAlign() const { 138 MaybeAlign A = decodeMaybeAlign(OrigAlign); 139 return A ? A->value() : 0; 140 } setOrigAlignArgFlagsTy141 void setOrigAlign(Align A) { 142 OrigAlign = encode(A); 143 assert(getOrigAlign() == A.value() && "bitfield overflow"); 144 } 145 getByValSizeArgFlagsTy146 unsigned getByValSize() const { return ByValSize; } setByValSizeArgFlagsTy147 void setByValSize(unsigned S) { ByValSize = S; } 148 getPointerAddrSpaceArgFlagsTy149 unsigned getPointerAddrSpace() const { return PointerAddrSpace; } setPointerAddrSpaceArgFlagsTy150 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; InputArgInputArg174 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 isOrigArgInputArg181 bool isOrigArg() const { 182 return OrigArgIndex != NoArgIndex; 183 } 184 getOrigArgIndexInputArg185 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; OutputArgOutputArg212 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