| //===- subzero/src/IceIntrinsics.h - List of Ice Intrinsics -----*- C++ -*-===// |
| // |
| // The Subzero Code Generator |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// \file |
| /// \brief Declares the kinds of intrinsics supported by PNaCl. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef SUBZERO_SRC_ICEINTRINSICS_H |
| #define SUBZERO_SRC_ICEINTRINSICS_H |
| |
| #include "IceDefs.h" |
| #include "IceStringPool.h" |
| #include "IceTypes.h" |
| |
| namespace Ice { |
| |
| class InstCall; |
| |
| static constexpr size_t kMaxIntrinsicParameters = 6; |
| |
| class Intrinsics { |
| Intrinsics(const Intrinsics &) = delete; |
| Intrinsics &operator=(const Intrinsics &) = delete; |
| |
| public: |
| explicit Intrinsics(GlobalContext *Ctx); |
| ~Intrinsics() = default; |
| |
| /// Some intrinsics allow overloading by type. This enum collapses all |
| /// overloads into a single ID, but the type can still be recovered by the |
| /// type of the intrinsic function call's return value and parameters. |
| enum IntrinsicID { |
| UnknownIntrinsic = 0, |
| // Arbitrary (alphabetical) order. |
| AtomicCmpxchg, |
| AtomicFence, |
| AtomicFenceAll, |
| AtomicIsLockFree, |
| AtomicLoad, |
| AtomicRMW, |
| AtomicStore, |
| Bswap, |
| Ctlz, |
| Ctpop, |
| Cttz, |
| Fabs, |
| Longjmp, |
| Memcpy, |
| Memmove, |
| Memset, |
| NaClReadTP, |
| Setjmp, |
| Sqrt, |
| Stacksave, |
| Stackrestore, |
| Trap, |
| // The intrinsics below are not part of the PNaCl specification. |
| AddSaturateSigned, |
| AddSaturateUnsigned, |
| LoadSubVector, |
| MultiplyAddPairs, |
| MultiplyHighSigned, |
| MultiplyHighUnsigned, |
| Nearbyint, |
| Round, |
| SignMask, |
| StoreSubVector, |
| SubtractSaturateSigned, |
| SubtractSaturateUnsigned, |
| VectorPackSigned, |
| VectorPackUnsigned |
| }; |
| |
| /// Operations that can be represented by the AtomicRMW intrinsic. |
| /// |
| /// Do not reorder these values: their order offers forward compatibility of |
| /// bitcode targeted to PNaCl. |
| enum AtomicRMWOperation { |
| AtomicInvalid = 0, // Invalid, keep first. |
| AtomicAdd, |
| AtomicSub, |
| AtomicOr, |
| AtomicAnd, |
| AtomicXor, |
| AtomicExchange, |
| AtomicNum // Invalid, keep last. |
| }; |
| |
| /// Memory orderings supported by PNaCl IR. |
| /// |
| /// Do not reorder these values: their order offers forward compatibility of |
| /// bitcode targeted to PNaCl. |
| enum MemoryOrder { |
| MemoryOrderInvalid = 0, // Invalid, keep first. |
| MemoryOrderRelaxed, |
| MemoryOrderConsume, |
| MemoryOrderAcquire, |
| MemoryOrderRelease, |
| MemoryOrderAcquireRelease, |
| MemoryOrderSequentiallyConsistent, |
| MemoryOrderNum // Invalid, keep last. |
| }; |
| |
| /// Verify memory ordering rules for atomic intrinsics. For AtomicCmpxchg, |
| /// Order is the "success" ordering and OrderOther is the "failure" ordering. |
| /// Returns true if valid, false if invalid. |
| // TODO(stichnot,kschimpf): Perform memory order validation in the bitcode |
| // reader/parser, allowing LLVM and Subzero to share. See |
| // https://code.google.com/p/nativeclient/issues/detail?id=4126 . |
| static bool isMemoryOrderValid(IntrinsicID ID, uint64_t Order, |
| uint64_t OrderOther = MemoryOrderInvalid); |
| |
| enum SideEffects { SideEffects_F = 0, SideEffects_T = 1 }; |
| |
| enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = 1 }; |
| |
| enum MemoryWrite { MemoryWrite_F = 0, MemoryWrite_T = 1 }; |
| |
| /// Basic attributes related to each intrinsic, that are relevant to code |
| /// generation. Perhaps the attributes representation can be shared with |
| /// general function calls, but PNaCl currently strips all attributes from |
| /// functions. |
| struct IntrinsicInfo { |
| enum IntrinsicID ID : 29; |
| enum SideEffects HasSideEffects : 1; |
| enum ReturnsTwice ReturnsTwice : 1; |
| enum MemoryWrite IsMemoryWrite : 1; |
| }; |
| static_assert(sizeof(IntrinsicInfo) == 4, "IntrinsicInfo should be 32 bits"); |
| |
| /// The types of validation values for FullIntrinsicInfo.validateCall. |
| enum ValidateCallValue { |
| IsValidCall, /// Valid use of instrinsic call. |
| BadReturnType, /// Return type invalid for intrinsic. |
| WrongNumOfArgs, /// Wrong number of arguments for intrinsic. |
| WrongCallArgType, /// Argument of wrong type. |
| }; |
| |
| /// The complete set of information about an intrinsic. |
| struct FullIntrinsicInfo { |
| struct IntrinsicInfo Info; /// Information that CodeGen would care about. |
| |
| // Sanity check during parsing. |
| Type Signature[kMaxIntrinsicParameters]; |
| uint8_t NumTypes; |
| |
| /// Validates that type signature of call matches intrinsic. If |
| /// WrongArgumentType is returned, ArgIndex is set to corresponding argument |
| /// index. |
| ValidateCallValue validateCall(const Ice::InstCall *Call, |
| SizeT &ArgIndex) const; |
| |
| /// Returns the return type of the intrinsic. |
| Type getReturnType() const { |
| assert(NumTypes > 0); |
| return Signature[0]; |
| } |
| |
| /// Returns number of arguments expected. |
| SizeT getNumArgs() const { |
| assert(NumTypes > 0); |
| return NumTypes - 1; |
| } |
| |
| /// Returns type of Index-th argument. |
| Type getArgType(SizeT Index) const; |
| }; |
| |
| /// Find the information about a given intrinsic, based on function name. If |
| /// the function name does not have the common "llvm." prefix, nullptr is |
| /// returned and Error is set to false. Otherwise, tries to find a reference |
| /// to a FullIntrinsicInfo entry (valid for the lifetime of the map). If |
| /// found, sets Error to false and returns the reference. If not found, sets |
| /// Error to true and returns nullptr (indicating an unknown "llvm.foo" |
| /// intrinsic). |
| const FullIntrinsicInfo *find(GlobalString Name, bool &Error) const; |
| |
| private: |
| // TODO(jvoung): May want to switch to something like LLVM's StringMap. |
| using IntrinsicMap = std::unordered_map<GlobalString, FullIntrinsicInfo>; |
| IntrinsicMap Map; |
| }; |
| |
| } // end of namespace Ice |
| |
| #endif // SUBZERO_SRC_ICEINTRINSICS_H |