• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- 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 /// \file
11 /// \brief Declares the kinds of intrinsics supported by PNaCl.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef SUBZERO_SRC_ICEINTRINSICS_H
16 #define SUBZERO_SRC_ICEINTRINSICS_H
17 
18 #include "IceDefs.h"
19 #include "IceStringPool.h"
20 #include "IceTypes.h"
21 
22 namespace Ice {
23 
24 class InstIntrinsic;
25 
26 static constexpr size_t kMaxIntrinsicParameters = 6;
27 
28 namespace Intrinsics {
29 
30 /// Some intrinsics allow overloading by type. This enum collapses all
31 /// overloads into a single ID, but the type can still be recovered by the
32 /// type of the intrinsic's return value and parameters.
33 enum IntrinsicID {
34   UnknownIntrinsic = 0,
35   // Arbitrary (alphabetical) order.
36   AtomicCmpxchg,
37   AtomicFence,
38   AtomicFenceAll,
39   AtomicIsLockFree,
40   AtomicLoad,
41   AtomicRMW,
42   AtomicStore,
43   Bswap,
44   Ctlz,
45   Ctpop,
46   Cttz,
47   Fabs,
48   Longjmp,
49   Memcpy,
50   Memmove,
51   Memset,
52   Setjmp,
53   Sqrt,
54   Stacksave,
55   Stackrestore,
56   Trap,
57   // The intrinsics below are not part of the PNaCl specification.
58   AddSaturateSigned,
59   AddSaturateUnsigned,
60   LoadSubVector,
61   MultiplyAddPairs,
62   MultiplyHighSigned,
63   MultiplyHighUnsigned,
64   Nearbyint,
65   Round,
66   SignMask,
67   StoreSubVector,
68   SubtractSaturateSigned,
69   SubtractSaturateUnsigned,
70   VectorPackSigned,
71   VectorPackUnsigned
72 };
73 
74 /// Operations that can be represented by the AtomicRMW intrinsic.
75 ///
76 /// Do not reorder these values: their order offers forward compatibility of
77 /// bitcode targeted to PNaCl.
78 enum AtomicRMWOperation {
79   AtomicInvalid = 0, // Invalid, keep first.
80   AtomicAdd,
81   AtomicSub,
82   AtomicOr,
83   AtomicAnd,
84   AtomicXor,
85   AtomicExchange,
86   AtomicNum // Invalid, keep last.
87 };
88 
89 /// Memory orderings supported by PNaCl IR.
90 ///
91 /// Do not reorder these values: their order offers forward compatibility of
92 /// bitcode targeted to PNaCl.
93 enum MemoryOrder {
94   MemoryOrderInvalid = 0, // Invalid, keep first.
95   MemoryOrderRelaxed,
96   MemoryOrderConsume,
97   MemoryOrderAcquire,
98   MemoryOrderRelease,
99   MemoryOrderAcquireRelease,
100   MemoryOrderSequentiallyConsistent,
101   MemoryOrderNum // Invalid, keep last.
102 };
103 
104 /// Verify memory ordering rules for atomic intrinsics. For AtomicCmpxchg,
105 /// Order is the "success" ordering and OrderOther is the "failure" ordering.
106 /// Returns true if valid, false if invalid.
107 // TODO(stichnot,kschimpf): Perform memory order validation in the bitcode
108 // reader/parser, allowing LLVM and Subzero to share. See
109 // https://code.google.com/p/nativeclient/issues/detail?id=4126 .
110 bool isMemoryOrderValid(IntrinsicID ID, uint64_t Order,
111                         uint64_t OrderOther = MemoryOrderInvalid);
112 
113 enum SideEffects { SideEffects_F = 0, SideEffects_T = 1 };
114 
115 enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = 1 };
116 
117 enum MemoryWrite { MemoryWrite_F = 0, MemoryWrite_T = 1 };
118 
119 /// Basic attributes related to each intrinsic, that are relevant to code
120 /// generation.
121 struct IntrinsicInfo {
122   enum IntrinsicID ID : 29;
123   enum SideEffects HasSideEffects : 1;
124   enum ReturnsTwice ReturnsTwice : 1;
125   enum MemoryWrite IsMemoryWrite : 1;
126 };
127 static_assert(sizeof(IntrinsicInfo) == 4, "IntrinsicInfo should be 32 bits");
128 
129 /// The types of validation values for FullIntrinsicInfo.validateIntrinsic.
130 enum ValidateIntrinsicValue {
131   IsValidIntrinsic, /// Valid use of instrinsic.
132   BadReturnType,    /// Return type invalid for intrinsic.
133   WrongNumOfArgs,   /// Wrong number of arguments for intrinsic.
134   WrongArgType,     /// Argument of wrong type.
135 };
136 
137 /// The complete set of information about an intrinsic.
138 struct FullIntrinsicInfo {
139   struct IntrinsicInfo Info; /// Information that CodeGen would care about.
140 
141   // Sanity check during parsing.
142   Type Signature[kMaxIntrinsicParameters];
143   uint8_t NumTypes;
144 
145   /// Validates that type signature matches intrinsic. If WrongArgumentType is
146   /// returned, ArgIndex is set to corresponding argument index.
147   ValidateIntrinsicValue validateIntrinsic(const Ice::InstIntrinsic *Intrinsic,
148                                            SizeT &ArgIndex) const;
149 
150   /// Returns the return type of the intrinsic.
getReturnTypeFullIntrinsicInfo151   Type getReturnType() const {
152     assert(NumTypes > 0);
153     return Signature[0];
154   }
155 
156   /// Returns number of arguments expected.
getNumArgsFullIntrinsicInfo157   SizeT getNumArgs() const {
158     assert(NumTypes > 0);
159     return NumTypes - 1;
160   }
161 
162   /// Returns type of Index-th argument.
163   Type getArgType(SizeT Index) const;
164 };
165 
166 } // namespace Intrinsics
167 
168 } // end of namespace Ice
169 
170 #endif // SUBZERO_SRC_ICEINTRINSICS_H
171