TargetCallingConv.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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. #ifndef LLVM_CODEGEN_TARGETCALLINGCONV_H
  13. #define LLVM_CODEGEN_TARGETCALLINGCONV_H
  14. #include "llvm/CodeGen/ValueTypes.h"
  15. #include "llvm/Support/Alignment.h"
  16. #include "llvm/Support/MachineValueType.h"
  17. #include "llvm/Support/MathExtras.h"
  18. #include <cassert>
  19. #include <climits>
  20. #include <cstdint>
  21. namespace llvm {
  22. namespace ISD {
  23. struct ArgFlagsTy {
  24. private:
  25. unsigned IsZExt : 1; ///< Zero extended
  26. unsigned IsSExt : 1; ///< Sign extended
  27. unsigned IsInReg : 1; ///< Passed in register
  28. unsigned IsSRet : 1; ///< Hidden struct-ret ptr
  29. unsigned IsByVal : 1; ///< Struct passed by value
  30. unsigned IsByRef : 1; ///< Passed in memory
  31. unsigned IsNest : 1; ///< Nested fn static chain
  32. unsigned IsReturned : 1; ///< Always returned
  33. unsigned IsSplit : 1;
  34. unsigned IsInAlloca : 1; ///< Passed with inalloca
  35. unsigned IsPreallocated : 1; ///< ByVal without the copy
  36. unsigned IsSplitEnd : 1; ///< Last part of a split
  37. unsigned IsSwiftSelf : 1; ///< Swift self parameter
  38. unsigned IsSwiftAsync : 1; ///< Swift async context parameter
  39. unsigned IsSwiftError : 1; ///< Swift error parameter
  40. unsigned IsCFGuardTarget : 1; ///< Control Flow Guard target
  41. unsigned IsHva : 1; ///< HVA field for
  42. unsigned IsHvaStart : 1; ///< HVA structure start
  43. unsigned IsSecArgPass : 1; ///< Second argument
  44. unsigned MemAlign : 4; ///< Log 2 of alignment when arg is passed in memory
  45. ///< (including byval/byref)
  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. unsigned ByValOrByRefSize; ///< Byval or byref struct size
  52. unsigned PointerAddrSpace; ///< Address space of pointer argument
  53. public:
  54. ArgFlagsTy()
  55. : IsZExt(0), IsSExt(0), IsInReg(0), IsSRet(0), IsByVal(0), IsByRef(0),
  56. IsNest(0), IsReturned(0), IsSplit(0), IsInAlloca(0),
  57. IsPreallocated(0), IsSplitEnd(0), IsSwiftSelf(0), IsSwiftAsync(0),
  58. IsSwiftError(0), IsCFGuardTarget(0), IsHva(0), IsHvaStart(0),
  59. IsSecArgPass(0), MemAlign(0), OrigAlign(0),
  60. IsInConsecutiveRegsLast(0), IsInConsecutiveRegs(0),
  61. IsCopyElisionCandidate(0), IsPointer(0), ByValOrByRefSize(0),
  62. PointerAddrSpace(0) {
  63. static_assert(sizeof(*this) == 3 * sizeof(unsigned), "flags are too big");
  64. }
  65. bool isZExt() const { return IsZExt; }
  66. void setZExt() { IsZExt = 1; }
  67. bool isSExt() const { return IsSExt; }
  68. void setSExt() { IsSExt = 1; }
  69. bool isInReg() const { return IsInReg; }
  70. void setInReg() { IsInReg = 1; }
  71. bool isSRet() const { return IsSRet; }
  72. void setSRet() { IsSRet = 1; }
  73. bool isByVal() const { return IsByVal; }
  74. void setByVal() { IsByVal = 1; }
  75. bool isByRef() const { return IsByRef; }
  76. void setByRef() { IsByRef = 1; }
  77. bool isInAlloca() const { return IsInAlloca; }
  78. void setInAlloca() { IsInAlloca = 1; }
  79. bool isPreallocated() const { return IsPreallocated; }
  80. void setPreallocated() { IsPreallocated = 1; }
  81. bool isSwiftSelf() const { return IsSwiftSelf; }
  82. void setSwiftSelf() { IsSwiftSelf = 1; }
  83. bool isSwiftAsync() const { return IsSwiftAsync; }
  84. void setSwiftAsync() { IsSwiftAsync = 1; }
  85. bool isSwiftError() const { return IsSwiftError; }
  86. void setSwiftError() { IsSwiftError = 1; }
  87. bool isCFGuardTarget() const { return IsCFGuardTarget; }
  88. void setCFGuardTarget() { IsCFGuardTarget = 1; }
  89. bool isHva() const { return IsHva; }
  90. void setHva() { IsHva = 1; }
  91. bool isHvaStart() const { return IsHvaStart; }
  92. void setHvaStart() { IsHvaStart = 1; }
  93. bool isSecArgPass() const { return IsSecArgPass; }
  94. void setSecArgPass() { IsSecArgPass = 1; }
  95. bool isNest() const { return IsNest; }
  96. void setNest() { IsNest = 1; }
  97. bool isReturned() const { return IsReturned; }
  98. void setReturned(bool V = true) { IsReturned = V; }
  99. bool isInConsecutiveRegs() const { return IsInConsecutiveRegs; }
  100. void setInConsecutiveRegs(bool Flag = true) { IsInConsecutiveRegs = Flag; }
  101. bool isInConsecutiveRegsLast() const { return IsInConsecutiveRegsLast; }
  102. void setInConsecutiveRegsLast(bool Flag = true) {
  103. IsInConsecutiveRegsLast = Flag;
  104. }
  105. bool isSplit() const { return IsSplit; }
  106. void setSplit() { IsSplit = 1; }
  107. bool isSplitEnd() const { return IsSplitEnd; }
  108. void setSplitEnd() { IsSplitEnd = 1; }
  109. bool isCopyElisionCandidate() const { return IsCopyElisionCandidate; }
  110. void setCopyElisionCandidate() { IsCopyElisionCandidate = 1; }
  111. bool isPointer() const { return IsPointer; }
  112. void setPointer() { IsPointer = 1; }
  113. Align getNonZeroMemAlign() const {
  114. return decodeMaybeAlign(MemAlign).valueOrOne();
  115. }
  116. void setMemAlign(Align A) {
  117. MemAlign = encode(A);
  118. assert(getNonZeroMemAlign() == A && "bitfield overflow");
  119. }
  120. Align getNonZeroByValAlign() const {
  121. assert(isByVal());
  122. MaybeAlign A = decodeMaybeAlign(MemAlign);
  123. assert(A && "ByValAlign must be defined");
  124. return *A;
  125. }
  126. Align getNonZeroOrigAlign() const {
  127. return decodeMaybeAlign(OrigAlign).valueOrOne();
  128. }
  129. void setOrigAlign(Align A) {
  130. OrigAlign = encode(A);
  131. assert(getNonZeroOrigAlign() == A && "bitfield overflow");
  132. }
  133. unsigned getByValSize() const {
  134. assert(isByVal() && !isByRef());
  135. return ByValOrByRefSize;
  136. }
  137. void setByValSize(unsigned S) {
  138. assert(isByVal() && !isByRef());
  139. ByValOrByRefSize = S;
  140. }
  141. unsigned getByRefSize() const {
  142. assert(!isByVal() && isByRef());
  143. return ByValOrByRefSize;
  144. }
  145. void setByRefSize(unsigned S) {
  146. assert(!isByVal() && isByRef());
  147. ByValOrByRefSize = S;
  148. }
  149. unsigned getPointerAddrSpace() const { return PointerAddrSpace; }
  150. void setPointerAddrSpace(unsigned AS) { PointerAddrSpace = AS; }
  151. };
  152. /// InputArg - This struct carries flags and type information about a
  153. /// single incoming (formal) argument or incoming (from the perspective
  154. /// of the caller) return value virtual register.
  155. ///
  156. struct InputArg {
  157. ArgFlagsTy Flags;
  158. MVT VT = MVT::Other;
  159. EVT ArgVT;
  160. bool Used = false;
  161. /// Index original Function's argument.
  162. unsigned OrigArgIndex;
  163. /// Sentinel value for implicit machine-level input arguments.
  164. static const unsigned NoArgIndex = UINT_MAX;
  165. /// Offset in bytes of current input value relative to the beginning of
  166. /// original argument. E.g. if argument was splitted into four 32 bit
  167. /// registers, we got 4 InputArgs with PartOffsets 0, 4, 8 and 12.
  168. unsigned PartOffset;
  169. InputArg() = default;
  170. InputArg(ArgFlagsTy flags, EVT vt, EVT argvt, bool used,
  171. unsigned origIdx, unsigned partOffs)
  172. : Flags(flags), Used(used), OrigArgIndex(origIdx), PartOffset(partOffs) {
  173. VT = vt.getSimpleVT();
  174. ArgVT = argvt;
  175. }
  176. bool isOrigArg() const {
  177. return OrigArgIndex != NoArgIndex;
  178. }
  179. unsigned getOrigArgIndex() const {
  180. assert(OrigArgIndex != NoArgIndex && "Implicit machine-level argument");
  181. return OrigArgIndex;
  182. }
  183. };
  184. /// OutputArg - This struct carries flags and a value for a
  185. /// single outgoing (actual) argument or outgoing (from the perspective
  186. /// of the caller) return value virtual register.
  187. ///
  188. struct OutputArg {
  189. ArgFlagsTy Flags;
  190. MVT VT;
  191. EVT ArgVT;
  192. /// IsFixed - Is this a "fixed" value, ie not passed through a vararg "...".
  193. bool IsFixed = false;
  194. /// Index original Function's argument.
  195. unsigned OrigArgIndex;
  196. /// Offset in bytes of current output value relative to the beginning of
  197. /// original argument. E.g. if argument was splitted into four 32 bit
  198. /// registers, we got 4 OutputArgs with PartOffsets 0, 4, 8 and 12.
  199. unsigned PartOffset;
  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. } // end namespace ISD
  210. } // end namespace llvm
  211. #endif // LLVM_CODEGEN_TARGETCALLINGCONV_H