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 NaClReadTP, 53 Setjmp, 54 Sqrt, 55 Stacksave, 56 Stackrestore, 57 Trap, 58 // The intrinsics below are not part of the PNaCl specification. 59 AddSaturateSigned, 60 AddSaturateUnsigned, 61 LoadSubVector, 62 MultiplyAddPairs, 63 MultiplyHighSigned, 64 MultiplyHighUnsigned, 65 Nearbyint, 66 Round, 67 SignMask, 68 StoreSubVector, 69 SubtractSaturateSigned, 70 SubtractSaturateUnsigned, 71 VectorPackSigned, 72 VectorPackUnsigned 73 }; 74 75 /// Operations that can be represented by the AtomicRMW intrinsic. 76 /// 77 /// Do not reorder these values: their order offers forward compatibility of 78 /// bitcode targeted to PNaCl. 79 enum AtomicRMWOperation { 80 AtomicInvalid = 0, // Invalid, keep first. 81 AtomicAdd, 82 AtomicSub, 83 AtomicOr, 84 AtomicAnd, 85 AtomicXor, 86 AtomicExchange, 87 AtomicNum // Invalid, keep last. 88 }; 89 90 /// Memory orderings supported by PNaCl IR. 91 /// 92 /// Do not reorder these values: their order offers forward compatibility of 93 /// bitcode targeted to PNaCl. 94 enum MemoryOrder { 95 MemoryOrderInvalid = 0, // Invalid, keep first. 96 MemoryOrderRelaxed, 97 MemoryOrderConsume, 98 MemoryOrderAcquire, 99 MemoryOrderRelease, 100 MemoryOrderAcquireRelease, 101 MemoryOrderSequentiallyConsistent, 102 MemoryOrderNum // Invalid, keep last. 103 }; 104 105 /// Verify memory ordering rules for atomic intrinsics. For AtomicCmpxchg, 106 /// Order is the "success" ordering and OrderOther is the "failure" ordering. 107 /// Returns true if valid, false if invalid. 108 // TODO(stichnot,kschimpf): Perform memory order validation in the bitcode 109 // reader/parser, allowing LLVM and Subzero to share. See 110 // https://code.google.com/p/nativeclient/issues/detail?id=4126 . 111 bool isMemoryOrderValid(IntrinsicID ID, uint64_t Order, 112 uint64_t OrderOther = MemoryOrderInvalid); 113 114 enum SideEffects { SideEffects_F = 0, SideEffects_T = 1 }; 115 116 enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = 1 }; 117 118 enum MemoryWrite { MemoryWrite_F = 0, MemoryWrite_T = 1 }; 119 120 /// Basic attributes related to each intrinsic, that are relevant to code 121 /// generation. 122 struct IntrinsicInfo { 123 enum IntrinsicID ID : 29; 124 enum SideEffects HasSideEffects : 1; 125 enum ReturnsTwice ReturnsTwice : 1; 126 enum MemoryWrite IsMemoryWrite : 1; 127 }; 128 static_assert(sizeof(IntrinsicInfo) == 4, "IntrinsicInfo should be 32 bits"); 129 130 /// The types of validation values for FullIntrinsicInfo.validateIntrinsic. 131 enum ValidateIntrinsicValue { 132 IsValidIntrinsic, /// Valid use of instrinsic. 133 BadReturnType, /// Return type invalid for intrinsic. 134 WrongNumOfArgs, /// Wrong number of arguments for intrinsic. 135 WrongArgType, /// Argument of wrong type. 136 }; 137 138 /// The complete set of information about an intrinsic. 139 struct FullIntrinsicInfo { 140 struct IntrinsicInfo Info; /// Information that CodeGen would care about. 141 142 // Sanity check during parsing. 143 Type Signature[kMaxIntrinsicParameters]; 144 uint8_t NumTypes; 145 146 /// Validates that type signature matches intrinsic. If WrongArgumentType is 147 /// returned, ArgIndex is set to corresponding argument index. 148 ValidateIntrinsicValue validateIntrinsic(const Ice::InstIntrinsic *Intrinsic, 149 SizeT &ArgIndex) const; 150 151 /// Returns the return type of the intrinsic. getReturnTypeFullIntrinsicInfo152 Type getReturnType() const { 153 assert(NumTypes > 0); 154 return Signature[0]; 155 } 156 157 /// Returns number of arguments expected. getNumArgsFullIntrinsicInfo158 SizeT getNumArgs() const { 159 assert(NumTypes > 0); 160 return NumTypes - 1; 161 } 162 163 /// Returns type of Index-th argument. 164 Type getArgType(SizeT Index) const; 165 }; 166 167 } // namespace Intrinsics 168 169 } // end of namespace Ice 170 171 #endif // SUBZERO_SRC_ICEINTRINSICS_H 172