blob: aea0bd202f12eb63e6c8b5193fea6d8ee6a03fbf [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,
63 Trap
64 };
65
Andrew Scull57e12682015-09-16 11:30:19 -070066 /// Operations that can be represented by the AtomicRMW intrinsic.
Jan Voung5cd240d2014-06-25 10:36:46 -070067 ///
Andrew Scull57e12682015-09-16 11:30:19 -070068 /// Do not reorder these values: their order offers forward compatibility of
69 /// bitcode targeted to PNaCl.
Jan Voung5cd240d2014-06-25 10:36:46 -070070 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 ///
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 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 Scull57e12682015-09-16 11:30:19 -070096 /// Verify memory ordering rules for atomic intrinsics. For AtomicCmpxchg,
97 /// Order is the "success" ordering and OrderOther is the "failure" ordering.
98 /// Returns true if valid, false if invalid.
99 // TODO(stichnot,kschimpf): Perform memory order validation in the bitcode
100 // reader/parser, allowing LLVM and Subzero to share. See
Jim Stichnoth1c335ef2015-03-18 09:01:52 -0700101 // 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 Scull57e12682015-09-16 11:30:19 -0700109 /// Basic attributes related to each intrinsic, that are relevant to code
110 /// generation. Perhaps the attributes representation can be shared with
111 /// general function calls, but PNaCl currently strips all attributes from
112 /// 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 Scull57e12682015-09-16 11:30:19 -0700135 /// Validates that type signature of call matches intrinsic. If
136 /// WrongArgumentType is returned, ArgIndex is set to corresponding argument
137 /// 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 {
Jim Stichnoth92b31442015-09-15 10:10:50 -0700143 assert(NumTypes > 0);
Karl Schimpf8df26f32014-09-19 09:33:26 -0700144 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 {
Jim Stichnoth92b31442015-09-15 10:10:50 -0700149 assert(NumTypes > 0);
Karl Schimpf8df26f32014-09-19 09:33:26 -0700150 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 Scull57e12682015-09-16 11:30:19 -0700157 /// Find the information about a given intrinsic, based on function name. If
Andrew Scull9612d322015-07-06 14:53:25 -0700158 /// the function name does not have the common "llvm." prefix, nullptr is
Andrew Scull57e12682015-09-16 11:30:19 -0700159 /// 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
Andrew Scull9612d322015-07-06 14:53:25 -0700162 /// Error to true and returns nullptr (indicating an unknown "llvm.foo"
163 /// intrinsic).
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700164 const FullIntrinsicInfo *find(GlobalString 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.
Jim Stichnoth467ffe52016-03-29 15:01:06 -0700168 using IntrinsicMap = std::unordered_map<GlobalString, FullIntrinsicInfo>;
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