xref: /aosp_15_r20/external/swiftshader/third_party/subzero/src/IceIntrinsics.h (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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 /// The _T values are set to -1 rather than 1 to avoid an implicit conversion
114 /// warning. A good explanation of the warning is here:
115 /// https://github.com/llvm/llvm-project/issues/53253.
116 /// Allows us to re-enable the warning in crbug.com/40234766
117 enum SideEffects { SideEffects_F = 0, SideEffects_T = -1 };
118 
119 enum ReturnsTwice { ReturnsTwice_F = 0, ReturnsTwice_T = -1 };
120 
121 enum MemoryWrite { MemoryWrite_F = 0, MemoryWrite_T = -1 };
122 
123 /// Basic attributes related to each intrinsic, that are relevant to code
124 /// generation.
125 struct IntrinsicInfo {
126   enum IntrinsicID ID : 29;
127   enum SideEffects HasSideEffects : 1;
128   enum ReturnsTwice ReturnsTwice : 1;
129   enum MemoryWrite IsMemoryWrite : 1;
130 };
131 static_assert(sizeof(IntrinsicInfo) == 4, "IntrinsicInfo should be 32 bits");
132 
133 /// The types of validation values for FullIntrinsicInfo.validateIntrinsic.
134 enum ValidateIntrinsicValue {
135   IsValidIntrinsic, /// Valid use of instrinsic.
136   BadReturnType,    /// Return type invalid for intrinsic.
137   WrongNumOfArgs,   /// Wrong number of arguments for intrinsic.
138   WrongArgType,     /// Argument of wrong type.
139 };
140 
141 /// The complete set of information about an intrinsic.
142 struct FullIntrinsicInfo {
143   struct IntrinsicInfo Info; /// Information that CodeGen would care about.
144 
145   // Sanity check during parsing.
146   Type Signature[kMaxIntrinsicParameters];
147   uint8_t NumTypes;
148 
149   /// Validates that type signature matches intrinsic. If WrongArgumentType is
150   /// returned, ArgIndex is set to corresponding argument index.
151   ValidateIntrinsicValue validateIntrinsic(const Ice::InstIntrinsic *Intrinsic,
152                                            SizeT &ArgIndex) const;
153 
154   /// Returns the return type of the intrinsic.
getReturnTypeFullIntrinsicInfo155   Type getReturnType() const {
156     assert(NumTypes > 0);
157     return Signature[0];
158   }
159 
160   /// Returns number of arguments expected.
getNumArgsFullIntrinsicInfo161   SizeT getNumArgs() const {
162     assert(NumTypes > 0);
163     return NumTypes - 1;
164   }
165 
166   /// Returns type of Index-th argument.
167   Type getArgType(SizeT Index) const;
168 };
169 
170 } // namespace Intrinsics
171 
172 } // end of namespace Ice
173 
174 #endif // SUBZERO_SRC_ICEINTRINSICS_H
175