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