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