blob: fb066b982b66a92ac0f5b34f50c44851f81d5786 [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//===----------------------------------------------------------------------===//
9//
10// This file declares the kinds of intrinsics supported by PNaCl.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef SUBZERO_SRC_ICEINTRINSICS_H
15#define SUBZERO_SRC_ICEINTRINSICS_H
16
17#include "IceDefs.h"
Karl Schimpfe1e013c2014-06-27 09:15:29 -070018#include "IceTypes.h"
Jan Voung3bd9f1a2014-06-18 10:50:57 -070019
20namespace Ice {
21
Karl Schimpf8df26f32014-09-19 09:33:26 -070022class InstCall;
23
Jan Voung3bd9f1a2014-06-18 10:50:57 -070024static const size_t kMaxIntrinsicParameters = 6;
25
26class Intrinsics {
Jim Stichnoth7b451a92014-10-15 14:39:23 -070027 Intrinsics(const Intrinsics &) = delete;
28 Intrinsics &operator=(const Intrinsics &) = delete;
29
Jan Voung3bd9f1a2014-06-18 10:50:57 -070030public:
31 Intrinsics();
32 ~Intrinsics();
33
34 // Some intrinsics allow overloading by type. This enum collapses all
35 // overloads into a single ID, but the type can still be recovered by the
36 // type of the intrinsic function call's return value and parameters.
37 enum IntrinsicID {
38 UnknownIntrinsic = 0,
39 // Arbitrary (alphabetical) order.
40 AtomicCmpxchg,
41 AtomicFence,
42 AtomicFenceAll,
43 AtomicIsLockFree,
44 AtomicLoad,
45 AtomicRMW,
46 AtomicStore,
47 Bswap,
48 Ctlz,
49 Ctpop,
50 Cttz,
51 Longjmp,
52 Memcpy,
53 Memmove,
54 Memset,
55 NaClReadTP,
56 Setjmp,
57 Sqrt,
58 Stacksave,
59 Stackrestore,
60 Trap
61 };
62
Jan Voung5cd240d2014-06-25 10:36:46 -070063 /// Operations that can be represented by the AtomicRMW
64 /// intrinsic.
65 ///
66 /// Do not reorder these values: their order offers forward
67 /// compatibility of bitcode targeted to PNaCl.
68 enum AtomicRMWOperation {
69 AtomicInvalid = 0, // Invalid, keep first.
70 AtomicAdd,
71 AtomicSub,
72 AtomicOr,
73 AtomicAnd,
74 AtomicXor,
75 AtomicExchange,
76 AtomicNum // Invalid, keep last.
77 };
78
79 /// Memory orderings supported by PNaCl IR.
80 ///
81 /// Do not reorder these values: their order offers forward
82 /// compatibility of bitcode targeted to PNaCl.
83 enum MemoryOrder {
84 MemoryOrderInvalid = 0, // Invalid, keep first.
85 MemoryOrderRelaxed,
86 MemoryOrderConsume,
87 MemoryOrderAcquire,
88 MemoryOrderRelease,
89 MemoryOrderAcquireRelease,
90 MemoryOrderSequentiallyConsistent,
91 MemoryOrderNum // Invalid, keep last.
92 };
93
94 static bool VerifyMemoryOrder(uint64_t Order);
95
Jim Stichnothdd842db2015-01-27 12:53:53 -080096 enum SideEffects { SideEffects_F = 0, SideEffects_T = 1 };
Jan Voung44d53e12014-09-11 19:18:03 -070097
Jim Stichnothdd842db2015-01-27 12:53:53 -080098 enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = 1 };
Jan Voung44d53e12014-09-11 19:18:03 -070099
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700100 // Basic attributes related to each intrinsic, that are relevant to
Jan Voung44d53e12014-09-11 19:18:03 -0700101 // code generation. Perhaps the attributes representation can be shared
102 // with general function calls, but PNaCl currently strips all
103 // attributes from functions.
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700104 struct IntrinsicInfo {
Jan Voung44d53e12014-09-11 19:18:03 -0700105 enum IntrinsicID ID : 30;
106 enum SideEffects HasSideEffects : 1;
107 enum ReturnsTwice ReturnsTwice : 1;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700108 };
109
Karl Schimpf8df26f32014-09-19 09:33:26 -0700110 // The types of validation values for FullIntrinsicInfo.validateCall.
111 enum ValidateCallValue {
112 IsValidCall, // Valid use of instrinsic call.
113 BadReturnType, // Return type invalid for intrinsic.
114 WrongNumOfArgs, // Wrong number of arguments for intrinsic.
115 WrongCallArgType, // Argument of wrong type.
116 };
117
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700118 // The complete set of information about an intrinsic.
119 struct FullIntrinsicInfo {
120 struct IntrinsicInfo Info; // Information that CodeGen would care about.
121
122 // Sanity check during parsing.
123 Type Signature[kMaxIntrinsicParameters];
124 uint8_t NumTypes;
Karl Schimpf8df26f32014-09-19 09:33:26 -0700125
126 // Validates that type signature of call matches intrinsic.
127 // If WrongArgumentType is returned, ArgIndex is set to corresponding
128 // argument index.
129 ValidateCallValue validateCall(const Ice::InstCall *Call,
130 SizeT &ArgIndex) const;
131
132 // Returns the return type of the intrinsic.
133 Type getReturnType() const {
134 assert(NumTypes > 1);
135 return Signature[0];
136 }
137
138 // Returns number of arguments expected.
139 SizeT getNumArgs() const {
140 assert(NumTypes > 1);
141 return NumTypes - 1;
142 }
143
144 // Returns type of Index-th argument.
145 Type getArgType(SizeT Index) const;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700146 };
147
Jim Stichnotha67fc442015-03-03 16:13:11 -0800148 // Find the information about a given intrinsic, based on function name. If
149 // the function name does not have the common "llvm." prefix, nullptr is
150 // returned and Error is set to false. Otherwise, tries to find a reference
151 // to a FullIntrinsicInfo entry (valid for the lifetime of the map). If
152 // found, sets Error to false and returns the reference. If not found, sets
153 // Error to true and returns nullptr (indicating an unknown "llvm.foo"
154 // intrinsic).
155 const FullIntrinsicInfo *find(const IceString &Name, bool &Error) const;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700156
157private:
158 // TODO(jvoung): May want to switch to something like LLVM's StringMap.
159 typedef std::map<IceString, FullIntrinsicInfo> IntrinsicMap;
Jim Stichnothf44f3712014-10-01 14:05:51 -0700160 IntrinsicMap Map;
Jan Voung3bd9f1a2014-06-18 10:50:57 -0700161};
162
163} // end of namespace Ice
164
165#endif // SUBZERO_SRC_ICEINTRINSICS_H