blob: 674c9ab2822fe0961eed734720cc48089ad97834 [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
11/// This file declares the kinds of intrinsics supported by PNaCl.
12///
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"
Karl Schimpfe1e013c2014-06-27 09:15:29 -070019#include "IceTypes.h"
Jan Voung3bd9f1a2014-06-18 10:50:57 -070020
21namespace Ice {
22
Karl Schimpf8df26f32014-09-19 09:33:26 -070023class InstCall;
24
Jan Voung3bd9f1a2014-06-18 10:50:57 -070025static const size_t kMaxIntrinsicParameters = 6;
26
27class Intrinsics {
Jim Stichnoth7b451a92014-10-15 14:39:23 -070028 Intrinsics(const Intrinsics &) = delete;
29 Intrinsics &operator=(const Intrinsics &) = delete;
30
Jan Voung3bd9f1a2014-06-18 10:50:57 -070031public:
32 Intrinsics();
33 ~Intrinsics();
34
Andrew Scull9612d322015-07-06 14:53:25 -070035 /// Some intrinsics allow overloading by type. This enum collapses all
36 /// overloads into a single ID, but the type can still be recovered by the
37 /// type of the intrinsic function call's return value and parameters.
Jan Voung3bd9f1a2014-06-18 10:50:57 -070038 enum IntrinsicID {
39 UnknownIntrinsic = 0,
40 // Arbitrary (alphabetical) order.
41 AtomicCmpxchg,
42 AtomicFence,
43 AtomicFenceAll,
44 AtomicIsLockFree,
45 AtomicLoad,
46 AtomicRMW,
47 AtomicStore,
48 Bswap,
49 Ctlz,
50 Ctpop,
51 Cttz,
Jim Stichnoth8c980d02015-03-19 13:01:50 -070052 Fabs,
Jan Voung3bd9f1a2014-06-18 10:50:57 -070053 Longjmp,
54 Memcpy,
55 Memmove,
56 Memset,
57 NaClReadTP,
58 Setjmp,
59 Sqrt,
60 Stacksave,
61 Stackrestore,
62 Trap
63 };
64
Jan Voung5cd240d2014-06-25 10:36:46 -070065 /// Operations that can be represented by the AtomicRMW
66 /// intrinsic.
67 ///
68 /// Do not reorder these values: their order offers forward
69 /// compatibility of bitcode targeted to PNaCl.
70 enum AtomicRMWOperation {
71 AtomicInvalid = 0, // Invalid, keep first.
72 AtomicAdd,
73 AtomicSub,
74 AtomicOr,
75 AtomicAnd,
76 AtomicXor,
77 AtomicExchange,
78 AtomicNum // Invalid, keep last.
79 };
80
81 /// Memory orderings supported by PNaCl IR.
82 ///
83 /// Do not reorder these values: their order offers forward
84 /// compatibility of bitcode targeted to PNaCl.
85 enum MemoryOrder {
86 MemoryOrderInvalid = 0, // Invalid, keep first.
87 MemoryOrderRelaxed,
88 MemoryOrderConsume,
89 MemoryOrderAcquire,
90 MemoryOrderRelease,
91 MemoryOrderAcquireRelease,
92 MemoryOrderSequentiallyConsistent,
93 MemoryOrderNum // Invalid, keep last.
94 };
95
Andrew Scull9612d322015-07-06 14:53:25 -070096 /// Verify memory ordering rules for atomic intrinsics. For
97 /// AtomicCmpxchg, Order is the "success" ordering and OrderOther is
98 /// the "failure" ordering. Returns true if valid, false if invalid.
Jim Stichnoth1c335ef2015-03-18 09:01:52 -070099 // TODO(stichnot,kschimpf): Perform memory order validation in the
100 // bitcode reader/parser, allowing LLVM and Subzero to share. See
101 // https://code.google.com/p/nativeclient/issues/detail?id=4126 .
102 static bool isMemoryOrderValid(IntrinsicID ID, uint64_t Order,
103 uint64_t OrderOther = MemoryOrderInvalid);
Jan Voung5cd240d2014-06-25 10:36:46 -0700104
Jim Stichnothdd842db2015-01-27 12:53:53 -0800105 enum SideEffects { SideEffects_F = 0, SideEffects_T = 1 };
Jan Voung44d53e12014-09-11 19:18:03 -0700106
Jim Stichnothdd842db2015-01-27 12:53:53 -0800107 enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = 1 };
Jan Voung44d53e12014-09-11 19:18:03 -0700108
Andrew Scull9612d322015-07-06 14:53:25 -0700109 /// Basic attributes related to each intrinsic, that are relevant to
110 /// code generation. Perhaps the attributes representation can be shared
111 /// with general function calls, but PNaCl currently strips all
112 /// attributes from functions.
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700113 struct IntrinsicInfo {
Jan Voung44d53e12014-09-11 19:18:03 -0700114 enum IntrinsicID ID : 30;
115 enum SideEffects HasSideEffects : 1;
116 enum ReturnsTwice ReturnsTwice : 1;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700117 };
118
Andrew Scull9612d322015-07-06 14:53:25 -0700119 /// The types of validation values for FullIntrinsicInfo.validateCall.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700120 enum ValidateCallValue {
Andrew Scull9612d322015-07-06 14:53:25 -0700121 IsValidCall, /// Valid use of instrinsic call.
122 BadReturnType, /// Return type invalid for intrinsic.
123 WrongNumOfArgs, /// Wrong number of arguments for intrinsic.
124 WrongCallArgType, /// Argument of wrong type.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700125 };
126
Andrew Scull9612d322015-07-06 14:53:25 -0700127 /// The complete set of information about an intrinsic.
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700128 struct FullIntrinsicInfo {
Andrew Scull9612d322015-07-06 14:53:25 -0700129 struct IntrinsicInfo Info; /// Information that CodeGen would care about.
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700130
131 // Sanity check during parsing.
132 Type Signature[kMaxIntrinsicParameters];
133 uint8_t NumTypes;
Karl Schimpf8df26f32014-09-19 09:33:26 -0700134
Andrew Scull9612d322015-07-06 14:53:25 -0700135 /// Validates that type signature of call matches intrinsic.
136 /// If WrongArgumentType is returned, ArgIndex is set to corresponding
137 /// argument index.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700138 ValidateCallValue validateCall(const Ice::InstCall *Call,
139 SizeT &ArgIndex) const;
140
Andrew Scull9612d322015-07-06 14:53:25 -0700141 /// Returns the return type of the intrinsic.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700142 Type getReturnType() const {
143 assert(NumTypes > 1);
144 return Signature[0];
145 }
146
Andrew Scull9612d322015-07-06 14:53:25 -0700147 /// Returns number of arguments expected.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700148 SizeT getNumArgs() const {
149 assert(NumTypes > 1);
150 return NumTypes - 1;
151 }
152
Andrew Scull9612d322015-07-06 14:53:25 -0700153 /// Returns type of Index-th argument.
Karl Schimpf8df26f32014-09-19 09:33:26 -0700154 Type getArgType(SizeT Index) const;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700155 };
156
Andrew Scull9612d322015-07-06 14:53:25 -0700157 /// Find the information about a given intrinsic, based on function name. If
158 /// the function name does not have the common "llvm." prefix, nullptr is
159 /// returned and Error is set to false. Otherwise, tries to find a reference
160 /// to a FullIntrinsicInfo entry (valid for the lifetime of the map). If
161 /// found, sets Error to false and returns the reference. If not found, sets
162 /// Error to true and returns nullptr (indicating an unknown "llvm.foo"
163 /// intrinsic).
Jim Stichnotha67fc442015-03-03 16:13:11 -0800164 const FullIntrinsicInfo *find(const IceString &Name, bool &Error) const;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700165
166private:
167 // TODO(jvoung): May want to switch to something like LLVM's StringMap.
168 typedef std::map<IceString, FullIntrinsicInfo> IntrinsicMap;
Jim Stichnothf44f3712014-10-01 14:05:51 -0700169 IntrinsicMap Map;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700170};
171
172} // end of namespace Ice
173
174#endif // SUBZERO_SRC_ICEINTRINSICS_H