blob: 54a02433671acac6fcc6bd6d67fc6fdbbc28505d [file] [log] [blame]
Jan Voung3bd9f1a2014-06-18 10:50:57 -07001//===- 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//===----------------------------------------------------------------------===//
Andrew Scull9612d322015-07-06 14:53:25 -07009///
10/// \file
Jim Stichnoth92a6e5b2015-12-02 16:52:44 -080011/// \brief Declares the kinds of intrinsics supported by PNaCl.
Andrew Scull9612d322015-07-06 14:53:25 -070012///
Jan Voung3bd9f1a2014-06-18 10:50:57 -070013//===----------------------------------------------------------------------===//
14
15#ifndef SUBZERO_SRC_ICEINTRINSICS_H
16#define SUBZERO_SRC_ICEINTRINSICS_H
17
18#include "IceDefs.h"
Jim Stichnoth467ffe52016-03-29 15:01:06 -070019#include "IceStringPool.h"
Karl Schimpfe1e013c2014-06-27 09:15:29 -070020#include "IceTypes.h"
Jan Voung3bd9f1a2014-06-18 10:50:57 -070021
22namespace Ice {
23
Karl Schimpf8df26f32014-09-19 09:33:26 -070024class InstCall;
25
Jim Stichnoth5bff61c2015-10-28 09:26:00 -070026static constexpr size_t kMaxIntrinsicParameters = 6;
Jan Voung3bd9f1a2014-06-18 10:50:57 -070027
28class Intrinsics {
Jim Stichnoth7b451a92014-10-15 14:39:23 -070029 Intrinsics(const Intrinsics &) = delete;
30 Intrinsics &operator=(const Intrinsics &) = delete;
31
Jan Voung3bd9f1a2014-06-18 10:50:57 -070032public:
Jim Stichnoth467ffe52016-03-29 15:01:06 -070033 explicit Intrinsics(GlobalContext *Ctx);
34 ~Intrinsics() = default;
Jan Voung3bd9f1a2014-06-18 10:50:57 -070035
Andrew Scull9612d322015-07-06 14:53:25 -070036 /// Some intrinsics allow overloading by type. This enum collapses all
37 /// overloads into a single ID, but the type can still be recovered by the
38 /// type of the intrinsic function call's return value and parameters.
Jan Voung3bd9f1a2014-06-18 10:50:57 -070039 enum IntrinsicID {
40 UnknownIntrinsic = 0,
41 // Arbitrary (alphabetical) order.
42 AtomicCmpxchg,
43 AtomicFence,
44 AtomicFenceAll,
45 AtomicIsLockFree,
46 AtomicLoad,
47 AtomicRMW,
48 AtomicStore,
49 Bswap,
50 Ctlz,
51 Ctpop,
52 Cttz,
Jim Stichnoth8c980d02015-03-19 13:01:50 -070053 Fabs,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070054 Longjmp,
55 Memcpy,
56 Memmove,
57 Memset,
58 NaClReadTP,
59 Setjmp,
60 Sqrt,
61 Stacksave,
62 Stackrestore,
Nicolas Capensacfb3df2016-10-03 10:46:30 -040063 Trap,
64 // The intrinsics below are not part of the PNaCl specification.
Nicolas Capens67a49b52016-10-26 13:18:35 -040065 AddSaturateSigned,
66 AddSaturateUnsigned,
Nicolas Capensacfb3df2016-10-03 10:46:30 -040067 LoadSubVector,
Nicolas Capens13cde0f2016-10-26 10:36:11 -040068 MultiplyAddPairs,
69 MultiplyHighSigned,
70 MultiplyHighUnsigned,
Nicolas Capensdbf81e02017-01-14 12:53:55 -050071 Nearbyint,
Nicolas Capensf0d12c32016-10-27 15:17:41 -040072 Round,
Nicolas Capens13cde0f2016-10-26 10:36:11 -040073 SignMask,
Nicolas Capensef8210d2016-10-17 17:42:29 -040074 StoreSubVector,
Nicolas Capens67a49b52016-10-26 13:18:35 -040075 SubtractSaturateSigned,
76 SubtractSaturateUnsigned,
Nicolas Capensef8210d2016-10-17 17:42:29 -040077 VectorPackSigned,
Nicolas Capens13cde0f2016-10-26 10:36:11 -040078 VectorPackUnsigned
Jan Voung3bd9f1a2014-06-18 10:50:57 -070079 };
80
Andrew Scull57e12682015-09-16 11:30:19 -070081 /// Operations that can be represented by the AtomicRMW intrinsic.
Jan Voung5cd240d2014-06-25 10:36:46 -070082 ///
Andrew Scull57e12682015-09-16 11:30:19 -070083 /// Do not reorder these values: their order offers forward compatibility of
84 /// bitcode targeted to PNaCl.
Jan Voung5cd240d2014-06-25 10:36:46 -070085 enum AtomicRMWOperation {
86 AtomicInvalid = 0, // Invalid, keep first.
87 AtomicAdd,
88 AtomicSub,
89 AtomicOr,
90 AtomicAnd,
91 AtomicXor,
92 AtomicExchange,
93 AtomicNum // Invalid, keep last.
94 };
95
96 /// Memory orderings supported by PNaCl IR.
97 ///
Andrew Scull57e12682015-09-16 11:30:19 -070098 /// Do not reorder these values: their order offers forward compatibility of
99 /// bitcode targeted to PNaCl.
Jan Voung5cd240d2014-06-25 10:36:46 -0700100 enum MemoryOrder {
101 MemoryOrderInvalid = 0, // Invalid, keep first.
102 MemoryOrderRelaxed,
103 MemoryOrderConsume,
104 MemoryOrderAcquire,
105 MemoryOrderRelease,
106 MemoryOrderAcquireRelease,
107 MemoryOrderSequentiallyConsistent,
108 MemoryOrderNum // Invalid, keep last.
109 };
110
Andrew Scull57e12682015-09-16 11:30:19 -0700111 /// Verify memory ordering rules for atomic intrinsics. For AtomicCmpxchg,
112 /// Order is the "success" ordering and OrderOther is the "failure" ordering.
113 /// Returns true if valid, false if invalid.
114 // TODO(stichnot,kschimpf): Perform memory order validation in the bitcode
115 // reader/parser, allowing LLVM and Subzero to share. See
Jim Stichnoth1c335ef2015-03-18 09:01:52 -0700116 // https://code.google.com/p/nativeclient/issues/detail?id=4126 .
117 static bool isMemoryOrderValid(IntrinsicID ID, uint64_t Order,
118 uint64_t OrderOther = MemoryOrderInvalid);
Jan Voung5cd240d2014-06-25 10:36:46 -0700119
Jim Stichnothdd842db2015-01-27 12:53:53 -0800120 enum SideEffects { SideEffects_F = 0, SideEffects_T = 1 };
Jan Voung44d53e12014-09-11 19:18:03 -0700121
Jim Stichnothdd842db2015-01-27 12:53:53 -0800122 enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = 1 };
Jan Voung44d53e12014-09-11 19:18:03 -0700123
Jim Stichnothf1f773d2016-04-21 16:54:33 -0700124 enum MemoryWrite { MemoryWrite_F = 0, MemoryWrite_T = 1 };
125
Andrew Scull57e12682015-09-16 11:30:19 -0700126 /// Basic attributes related to each intrinsic, that are relevant to code
127 /// generation. Perhaps the attributes representation can be shared with
128 /// general function calls, but PNaCl currently strips all attributes from
129 /// functions.
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700130 struct IntrinsicInfo {
Jim Stichnothf1f773d2016-04-21 16:54:33 -0700131 enum IntrinsicID ID : 29;
Jan Voung44d53e12014-09-11 19:18:03 -0700132 enum SideEffects HasSideEffects : 1;
133 enum ReturnsTwice ReturnsTwice : 1;
Jim Stichnothf1f773d2016-04-21 16:54:33 -0700134 enum MemoryWrite IsMemoryWrite : 1;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700135 };
Jim Stichnothf1f773d2016-04-21 16:54:33 -0700136 static_assert(sizeof(IntrinsicInfo) == 4, "IntrinsicInfo should be 32 bits");
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700137
Andrew Scull9612d322015-07-06 14:53:25 -0700138 /// The types of validation values for FullIntrinsicInfo.validateCall.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700139 enum ValidateCallValue {
Andrew Scull9612d322015-07-06 14:53:25 -0700140 IsValidCall, /// Valid use of instrinsic call.
141 BadReturnType, /// Return type invalid for intrinsic.
142 WrongNumOfArgs, /// Wrong number of arguments for intrinsic.
143 WrongCallArgType, /// Argument of wrong type.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700144 };
145
Andrew Scull9612d322015-07-06 14:53:25 -0700146 /// The complete set of information about an intrinsic.
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700147 struct FullIntrinsicInfo {
Andrew Scull9612d322015-07-06 14:53:25 -0700148 struct IntrinsicInfo Info; /// Information that CodeGen would care about.
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700149
150 // Sanity check during parsing.
151 Type Signature[kMaxIntrinsicParameters];
152 uint8_t NumTypes;
Karl Schimpf8df26f32014-09-19 09:33:26 -0700153
Andrew Scull57e12682015-09-16 11:30:19 -0700154 /// Validates that type signature of call matches intrinsic. If
155 /// WrongArgumentType is returned, ArgIndex is set to corresponding argument
156 /// index.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700157 ValidateCallValue validateCall(const Ice::InstCall *Call,
158 SizeT &ArgIndex) const;
159
Andrew Scull9612d322015-07-06 14:53:25 -0700160 /// Returns the return type of the intrinsic.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700161 Type getReturnType() const {
Jim Stichnoth92b31442015-09-15 10:10:50 -0700162 assert(NumTypes > 0);
Karl Schimpf8df26f32014-09-19 09:33:26 -0700163 return Signature[0];
164 }
165
Andrew Scull9612d322015-07-06 14:53:25 -0700166 /// Returns number of arguments expected.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700167 SizeT getNumArgs() const {
Jim Stichnoth92b31442015-09-15 10:10:50 -0700168 assert(NumTypes > 0);
Karl Schimpf8df26f32014-09-19 09:33:26 -0700169 return NumTypes - 1;
170 }
171
Andrew Scull9612d322015-07-06 14:53:25 -0700172 /// Returns type of Index-th argument.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700173 Type getArgType(SizeT Index) const;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700174 };
175
Andrew Scull57e12682015-09-16 11:30:19 -0700176 /// Find the information about a given intrinsic, based on function name. If
Andrew Scull9612d322015-07-06 14:53:25 -0700177 /// the function name does not have the common "llvm." prefix, nullptr is
Andrew Scull57e12682015-09-16 11:30:19 -0700178 /// returned and Error is set to false. Otherwise, tries to find a reference
179 /// to a FullIntrinsicInfo entry (valid for the lifetime of the map). If
180 /// found, sets Error to false and returns the reference. If not found, sets
Andrew Scull9612d322015-07-06 14:53:25 -0700181 /// Error to true and returns nullptr (indicating an unknown "llvm.foo"
182 /// intrinsic).
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700183 const FullIntrinsicInfo *find(GlobalString Name, bool &Error) const;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700184
185private:
186 // TODO(jvoung): May want to switch to something like LLVM's StringMap.
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700187 using IntrinsicMap = std::unordered_map<GlobalString, FullIntrinsicInfo>;
Jim Stichnothf44f3712014-10-01 14:05:51 -0700188 IntrinsicMap Map;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700189};
190
191} // end of namespace Ice
192
193#endif // SUBZERO_SRC_ICEINTRINSICS_H