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