1 //===- subzero/src/IceIntrinsics.h - List of Ice Intrinsics -----*- C++ -*-===// 2 // 3 // The Subzero Code Generator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Declares the kinds of intrinsics supported by PNaCl. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #ifndef SUBZERO_SRC_ICEINTRINSICS_H 16 #define SUBZERO_SRC_ICEINTRINSICS_H 17 18 #include "IceDefs.h" 19 #include "IceStringPool.h" 20 #include "IceTypes.h" 21 22 namespace Ice { 23 24 class InstIntrinsic; 25 26 static constexpr size_t kMaxIntrinsicParameters = 6; 27 28 namespace Intrinsics { 29 30 /// Some intrinsics allow overloading by type. This enum collapses all 31 /// overloads into a single ID, but the type can still be recovered by the 32 /// type of the intrinsic's return value and parameters. 33 enum IntrinsicID { 34 UnknownIntrinsic = 0, 35 // Arbitrary (alphabetical) order. 36 AtomicCmpxchg, 37 AtomicFence, 38 AtomicFenceAll, 39 AtomicIsLockFree, 40 AtomicLoad, 41 AtomicRMW, 42 AtomicStore, 43 Bswap, 44 Ctlz, 45 Ctpop, 46 Cttz, 47 Fabs, 48 Longjmp, 49 Memcpy, 50 Memmove, 51 Memset, 52 Setjmp, 53 Sqrt, 54 Stacksave, 55 Stackrestore, 56 Trap, 57 // The intrinsics below are not part of the PNaCl specification. 58 AddSaturateSigned, 59 AddSaturateUnsigned, 60 LoadSubVector, 61 MultiplyAddPairs, 62 MultiplyHighSigned, 63 MultiplyHighUnsigned, 64 Nearbyint, 65 Round, 66 SignMask, 67 StoreSubVector, 68 SubtractSaturateSigned, 69 SubtractSaturateUnsigned, 70 VectorPackSigned, 71 VectorPackUnsigned 72 }; 73 74 /// Operations that can be represented by the AtomicRMW intrinsic. 75 /// 76 /// Do not reorder these values: their order offers forward compatibility of 77 /// bitcode targeted to PNaCl. 78 enum AtomicRMWOperation { 79 AtomicInvalid = 0, // Invalid, keep first. 80 AtomicAdd, 81 AtomicSub, 82 AtomicOr, 83 AtomicAnd, 84 AtomicXor, 85 AtomicExchange, 86 AtomicNum // Invalid, keep last. 87 }; 88 89 /// Memory orderings supported by PNaCl IR. 90 /// 91 /// Do not reorder these values: their order offers forward compatibility of 92 /// bitcode targeted to PNaCl. 93 enum MemoryOrder { 94 MemoryOrderInvalid = 0, // Invalid, keep first. 95 MemoryOrderRelaxed, 96 MemoryOrderConsume, 97 MemoryOrderAcquire, 98 MemoryOrderRelease, 99 MemoryOrderAcquireRelease, 100 MemoryOrderSequentiallyConsistent, 101 MemoryOrderNum // Invalid, keep last. 102 }; 103 104 /// Verify memory ordering rules for atomic intrinsics. For AtomicCmpxchg, 105 /// Order is the "success" ordering and OrderOther is the "failure" ordering. 106 /// Returns true if valid, false if invalid. 107 // TODO(stichnot,kschimpf): Perform memory order validation in the bitcode 108 // reader/parser, allowing LLVM and Subzero to share. See 109 // https://code.google.com/p/nativeclient/issues/detail?id=4126 . 110 bool isMemoryOrderValid(IntrinsicID ID, uint64_t Order, 111 uint64_t OrderOther = MemoryOrderInvalid); 112 113 /// The _T values are set to -1 rather than 1 to avoid an implicit conversion 114 /// warning. A good explanation of the warning is here: 115 /// https://github.com/llvm/llvm-project/issues/53253. 116 /// Allows us to re-enable the warning in crbug.com/40234766 117 enum SideEffects { SideEffects_F = 0, SideEffects_T = -1 }; 118 119 enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = -1 }; 120 121 enum MemoryWrite { MemoryWrite_F = 0, MemoryWrite_T = -1 }; 122 123 /// Basic attributes related to each intrinsic, that are relevant to code 124 /// generation. 125 struct IntrinsicInfo { 126 enum IntrinsicID ID : 29; 127 enum SideEffects HasSideEffects : 1; 128 enum ReturnsTwice ReturnsTwice : 1; 129 enum MemoryWrite IsMemoryWrite : 1; 130 }; 131 static_assert(sizeof(IntrinsicInfo) == 4, "IntrinsicInfo should be 32 bits"); 132 133 /// The types of validation values for FullIntrinsicInfo.validateIntrinsic. 134 enum ValidateIntrinsicValue { 135 IsValidIntrinsic, /// Valid use of instrinsic. 136 BadReturnType, /// Return type invalid for intrinsic. 137 WrongNumOfArgs, /// Wrong number of arguments for intrinsic. 138 WrongArgType, /// Argument of wrong type. 139 }; 140 141 /// The complete set of information about an intrinsic. 142 struct FullIntrinsicInfo { 143 struct IntrinsicInfo Info; /// Information that CodeGen would care about. 144 145 // Sanity check during parsing. 146 Type Signature[kMaxIntrinsicParameters]; 147 uint8_t NumTypes; 148 149 /// Validates that type signature matches intrinsic. If WrongArgumentType is 150 /// returned, ArgIndex is set to corresponding argument index. 151 ValidateIntrinsicValue validateIntrinsic(const Ice::InstIntrinsic *Intrinsic, 152 SizeT &ArgIndex) const; 153 154 /// Returns the return type of the intrinsic. getReturnTypeFullIntrinsicInfo155 Type getReturnType() const { 156 assert(NumTypes > 0); 157 return Signature[0]; 158 } 159 160 /// Returns number of arguments expected. getNumArgsFullIntrinsicInfo161 SizeT getNumArgs() const { 162 assert(NumTypes > 0); 163 return NumTypes - 1; 164 } 165 166 /// Returns type of Index-th argument. 167 Type getArgType(SizeT Index) const; 168 }; 169 170 } // namespace Intrinsics 171 172 } // end of namespace Ice 173 174 #endif // SUBZERO_SRC_ICEINTRINSICS_H 175