xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPULibFunc.h (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- AMDGPULibFunc.h ----------------------------------------*- C++ -*--===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #ifndef _AMDGPU_LIBFUNC_H_
10*0b57cec5SDimitry Andric #define _AMDGPU_LIBFUNC_H_
11*0b57cec5SDimitry Andric 
12*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
13*0b57cec5SDimitry Andric 
14*0b57cec5SDimitry Andric namespace llvm {
15*0b57cec5SDimitry Andric 
16*0b57cec5SDimitry Andric class FunctionType;
17*0b57cec5SDimitry Andric class Function;
18*0b57cec5SDimitry Andric class Module;
19*0b57cec5SDimitry Andric 
20*0b57cec5SDimitry Andric class AMDGPULibFuncBase {
21*0b57cec5SDimitry Andric public:
22*0b57cec5SDimitry Andric   enum EFuncId {
23*0b57cec5SDimitry Andric     EI_NONE,
24*0b57cec5SDimitry Andric 
25*0b57cec5SDimitry Andric     // IMPORTANT: enums below should go in ascending by 1 value order
26*0b57cec5SDimitry Andric     // because they are used as indexes in the mangling rules table.
27*0b57cec5SDimitry Andric     // don't use explicit value assignment.
28*0b57cec5SDimitry Andric     //
29*0b57cec5SDimitry Andric     // There are two types of library functions: those with mangled
30*0b57cec5SDimitry Andric     // name and those with unmangled name. The enums for the library
31*0b57cec5SDimitry Andric     // functions with mangled name are defined before enums for the
32*0b57cec5SDimitry Andric     // library functions with unmangled name. The enum for the last
33*0b57cec5SDimitry Andric     // library function with mangled name is EI_LAST_MANGLED.
34*0b57cec5SDimitry Andric     //
35*0b57cec5SDimitry Andric     // Library functions with mangled name.
36*0b57cec5SDimitry Andric     EI_ABS,
37*0b57cec5SDimitry Andric     EI_ABS_DIFF,
38*0b57cec5SDimitry Andric     EI_ACOS,
39*0b57cec5SDimitry Andric     EI_ACOSH,
40*0b57cec5SDimitry Andric     EI_ACOSPI,
41*0b57cec5SDimitry Andric     EI_ADD_SAT,
42*0b57cec5SDimitry Andric     EI_ALL,
43*0b57cec5SDimitry Andric     EI_ANY,
44*0b57cec5SDimitry Andric     EI_ASIN,
45*0b57cec5SDimitry Andric     EI_ASINH,
46*0b57cec5SDimitry Andric     EI_ASINPI,
47*0b57cec5SDimitry Andric     EI_ASYNC_WORK_GROUP_COPY,
48*0b57cec5SDimitry Andric     EI_ASYNC_WORK_GROUP_STRIDED_COPY,
49*0b57cec5SDimitry Andric     EI_ATAN,
50*0b57cec5SDimitry Andric     EI_ATAN2,
51*0b57cec5SDimitry Andric     EI_ATAN2PI,
52*0b57cec5SDimitry Andric     EI_ATANH,
53*0b57cec5SDimitry Andric     EI_ATANPI,
54*0b57cec5SDimitry Andric     EI_ATOMIC_ADD,
55*0b57cec5SDimitry Andric     EI_ATOMIC_AND,
56*0b57cec5SDimitry Andric     EI_ATOMIC_CMPXCHG,
57*0b57cec5SDimitry Andric     EI_ATOMIC_DEC,
58*0b57cec5SDimitry Andric     EI_ATOMIC_INC,
59*0b57cec5SDimitry Andric     EI_ATOMIC_MAX,
60*0b57cec5SDimitry Andric     EI_ATOMIC_MIN,
61*0b57cec5SDimitry Andric     EI_ATOMIC_OR,
62*0b57cec5SDimitry Andric     EI_ATOMIC_SUB,
63*0b57cec5SDimitry Andric     EI_ATOMIC_XCHG,
64*0b57cec5SDimitry Andric     EI_ATOMIC_XOR,
65*0b57cec5SDimitry Andric     EI_BITSELECT,
66*0b57cec5SDimitry Andric     EI_CBRT,
67*0b57cec5SDimitry Andric     EI_CEIL,
68*0b57cec5SDimitry Andric     EI_CLAMP,
69*0b57cec5SDimitry Andric     EI_CLZ,
70*0b57cec5SDimitry Andric     EI_COMMIT_READ_PIPE,
71*0b57cec5SDimitry Andric     EI_COMMIT_WRITE_PIPE,
72*0b57cec5SDimitry Andric     EI_COPYSIGN,
73*0b57cec5SDimitry Andric     EI_COS,
74*0b57cec5SDimitry Andric     EI_COSH,
75*0b57cec5SDimitry Andric     EI_COSPI,
76*0b57cec5SDimitry Andric     EI_CROSS,
77*0b57cec5SDimitry Andric     EI_CTZ,
78*0b57cec5SDimitry Andric     EI_DEGREES,
79*0b57cec5SDimitry Andric     EI_DISTANCE,
80*0b57cec5SDimitry Andric     EI_DIVIDE,
81*0b57cec5SDimitry Andric     EI_DOT,
82*0b57cec5SDimitry Andric     EI_ERF,
83*0b57cec5SDimitry Andric     EI_ERFC,
84*0b57cec5SDimitry Andric     EI_EXP,
85*0b57cec5SDimitry Andric     EI_EXP10,
86*0b57cec5SDimitry Andric     EI_EXP2,
87*0b57cec5SDimitry Andric     EI_EXPM1,
88*0b57cec5SDimitry Andric     EI_FABS,
89*0b57cec5SDimitry Andric     EI_FAST_DISTANCE,
90*0b57cec5SDimitry Andric     EI_FAST_LENGTH,
91*0b57cec5SDimitry Andric     EI_FAST_NORMALIZE,
92*0b57cec5SDimitry Andric     EI_FDIM,
93*0b57cec5SDimitry Andric     EI_FLOOR,
94*0b57cec5SDimitry Andric     EI_FMA,
95*0b57cec5SDimitry Andric     EI_FMAX,
96*0b57cec5SDimitry Andric     EI_FMIN,
97*0b57cec5SDimitry Andric     EI_FMOD,
98*0b57cec5SDimitry Andric     EI_FRACT,
99*0b57cec5SDimitry Andric     EI_FREXP,
100*0b57cec5SDimitry Andric     EI_GET_IMAGE_ARRAY_SIZE,
101*0b57cec5SDimitry Andric     EI_GET_IMAGE_CHANNEL_DATA_TYPE,
102*0b57cec5SDimitry Andric     EI_GET_IMAGE_CHANNEL_ORDER,
103*0b57cec5SDimitry Andric     EI_GET_IMAGE_DIM,
104*0b57cec5SDimitry Andric     EI_GET_IMAGE_HEIGHT,
105*0b57cec5SDimitry Andric     EI_GET_IMAGE_WIDTH,
106*0b57cec5SDimitry Andric     EI_GET_PIPE_MAX_PACKETS,
107*0b57cec5SDimitry Andric     EI_GET_PIPE_NUM_PACKETS,
108*0b57cec5SDimitry Andric     EI_HADD,
109*0b57cec5SDimitry Andric     EI_HYPOT,
110*0b57cec5SDimitry Andric     EI_ILOGB,
111*0b57cec5SDimitry Andric     EI_ISEQUAL,
112*0b57cec5SDimitry Andric     EI_ISFINITE,
113*0b57cec5SDimitry Andric     EI_ISGREATER,
114*0b57cec5SDimitry Andric     EI_ISGREATEREQUAL,
115*0b57cec5SDimitry Andric     EI_ISINF,
116*0b57cec5SDimitry Andric     EI_ISLESS,
117*0b57cec5SDimitry Andric     EI_ISLESSEQUAL,
118*0b57cec5SDimitry Andric     EI_ISLESSGREATER,
119*0b57cec5SDimitry Andric     EI_ISNAN,
120*0b57cec5SDimitry Andric     EI_ISNORMAL,
121*0b57cec5SDimitry Andric     EI_ISNOTEQUAL,
122*0b57cec5SDimitry Andric     EI_ISORDERED,
123*0b57cec5SDimitry Andric     EI_ISUNORDERED,
124*0b57cec5SDimitry Andric     EI_LDEXP,
125*0b57cec5SDimitry Andric     EI_LENGTH,
126*0b57cec5SDimitry Andric     EI_LGAMMA,
127*0b57cec5SDimitry Andric     EI_LGAMMA_R,
128*0b57cec5SDimitry Andric     EI_LOG,
129*0b57cec5SDimitry Andric     EI_LOG10,
130*0b57cec5SDimitry Andric     EI_LOG1P,
131*0b57cec5SDimitry Andric     EI_LOG2,
132*0b57cec5SDimitry Andric     EI_LOGB,
133*0b57cec5SDimitry Andric     EI_MAD,
134*0b57cec5SDimitry Andric     EI_MAD24,
135*0b57cec5SDimitry Andric     EI_MAD_HI,
136*0b57cec5SDimitry Andric     EI_MAD_SAT,
137*0b57cec5SDimitry Andric     EI_MAX,
138*0b57cec5SDimitry Andric     EI_MAXMAG,
139*0b57cec5SDimitry Andric     EI_MIN,
140*0b57cec5SDimitry Andric     EI_MINMAG,
141*0b57cec5SDimitry Andric     EI_MIX,
142*0b57cec5SDimitry Andric     EI_MODF,
143*0b57cec5SDimitry Andric     EI_MUL24,
144*0b57cec5SDimitry Andric     EI_MUL_HI,
145*0b57cec5SDimitry Andric     EI_NAN,
146*0b57cec5SDimitry Andric     EI_NEXTAFTER,
147*0b57cec5SDimitry Andric     EI_NORMALIZE,
148*0b57cec5SDimitry Andric     EI_POPCOUNT,
149*0b57cec5SDimitry Andric     EI_POW,
150*0b57cec5SDimitry Andric     EI_POWN,
151*0b57cec5SDimitry Andric     EI_POWR,
152*0b57cec5SDimitry Andric     EI_PREFETCH,
153*0b57cec5SDimitry Andric     EI_RADIANS,
154*0b57cec5SDimitry Andric     EI_RECIP,
155*0b57cec5SDimitry Andric     EI_REMAINDER,
156*0b57cec5SDimitry Andric     EI_REMQUO,
157*0b57cec5SDimitry Andric     EI_RESERVE_READ_PIPE,
158*0b57cec5SDimitry Andric     EI_RESERVE_WRITE_PIPE,
159*0b57cec5SDimitry Andric     EI_RHADD,
160*0b57cec5SDimitry Andric     EI_RINT,
161*0b57cec5SDimitry Andric     EI_ROOTN,
162*0b57cec5SDimitry Andric     EI_ROTATE,
163*0b57cec5SDimitry Andric     EI_ROUND,
164*0b57cec5SDimitry Andric     EI_RSQRT,
165*0b57cec5SDimitry Andric     EI_SELECT,
166*0b57cec5SDimitry Andric     EI_SHUFFLE,
167*0b57cec5SDimitry Andric     EI_SHUFFLE2,
168*0b57cec5SDimitry Andric     EI_SIGN,
169*0b57cec5SDimitry Andric     EI_SIGNBIT,
170*0b57cec5SDimitry Andric     EI_SIN,
171*0b57cec5SDimitry Andric     EI_SINCOS,
172*0b57cec5SDimitry Andric     EI_SINH,
173*0b57cec5SDimitry Andric     EI_SINPI,
174*0b57cec5SDimitry Andric     EI_SMOOTHSTEP,
175*0b57cec5SDimitry Andric     EI_SQRT,
176*0b57cec5SDimitry Andric     EI_STEP,
177*0b57cec5SDimitry Andric     EI_SUB_GROUP_BROADCAST,
178*0b57cec5SDimitry Andric     EI_SUB_GROUP_COMMIT_READ_PIPE,
179*0b57cec5SDimitry Andric     EI_SUB_GROUP_COMMIT_WRITE_PIPE,
180*0b57cec5SDimitry Andric     EI_SUB_GROUP_REDUCE_ADD,
181*0b57cec5SDimitry Andric     EI_SUB_GROUP_REDUCE_MAX,
182*0b57cec5SDimitry Andric     EI_SUB_GROUP_REDUCE_MIN,
183*0b57cec5SDimitry Andric     EI_SUB_GROUP_RESERVE_READ_PIPE,
184*0b57cec5SDimitry Andric     EI_SUB_GROUP_RESERVE_WRITE_PIPE,
185*0b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_EXCLUSIVE_ADD,
186*0b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_EXCLUSIVE_MAX,
187*0b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_EXCLUSIVE_MIN,
188*0b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_INCLUSIVE_ADD,
189*0b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_INCLUSIVE_MAX,
190*0b57cec5SDimitry Andric     EI_SUB_GROUP_SCAN_INCLUSIVE_MIN,
191*0b57cec5SDimitry Andric     EI_SUB_SAT,
192*0b57cec5SDimitry Andric     EI_TAN,
193*0b57cec5SDimitry Andric     EI_TANH,
194*0b57cec5SDimitry Andric     EI_TANPI,
195*0b57cec5SDimitry Andric     EI_TGAMMA,
196*0b57cec5SDimitry Andric     EI_TRUNC,
197*0b57cec5SDimitry Andric     EI_UPSAMPLE,
198*0b57cec5SDimitry Andric     EI_VEC_STEP,
199*0b57cec5SDimitry Andric     EI_VSTORE,
200*0b57cec5SDimitry Andric     EI_VSTORE16,
201*0b57cec5SDimitry Andric     EI_VSTORE2,
202*0b57cec5SDimitry Andric     EI_VSTORE3,
203*0b57cec5SDimitry Andric     EI_VSTORE4,
204*0b57cec5SDimitry Andric     EI_VSTORE8,
205*0b57cec5SDimitry Andric     EI_WORK_GROUP_COMMIT_READ_PIPE,
206*0b57cec5SDimitry Andric     EI_WORK_GROUP_COMMIT_WRITE_PIPE,
207*0b57cec5SDimitry Andric     EI_WORK_GROUP_REDUCE_ADD,
208*0b57cec5SDimitry Andric     EI_WORK_GROUP_REDUCE_MAX,
209*0b57cec5SDimitry Andric     EI_WORK_GROUP_REDUCE_MIN,
210*0b57cec5SDimitry Andric     EI_WORK_GROUP_RESERVE_READ_PIPE,
211*0b57cec5SDimitry Andric     EI_WORK_GROUP_RESERVE_WRITE_PIPE,
212*0b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_EXCLUSIVE_ADD,
213*0b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_EXCLUSIVE_MAX,
214*0b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_EXCLUSIVE_MIN,
215*0b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_INCLUSIVE_ADD,
216*0b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_INCLUSIVE_MAX,
217*0b57cec5SDimitry Andric     EI_WORK_GROUP_SCAN_INCLUSIVE_MIN,
218*0b57cec5SDimitry Andric     EI_WRITE_IMAGEF,
219*0b57cec5SDimitry Andric     EI_WRITE_IMAGEI,
220*0b57cec5SDimitry Andric     EI_WRITE_IMAGEUI,
221*0b57cec5SDimitry Andric     EI_NCOS,
222*0b57cec5SDimitry Andric     EI_NEXP2,
223*0b57cec5SDimitry Andric     EI_NFMA,
224*0b57cec5SDimitry Andric     EI_NLOG2,
225*0b57cec5SDimitry Andric     EI_NRCP,
226*0b57cec5SDimitry Andric     EI_NRSQRT,
227*0b57cec5SDimitry Andric     EI_NSIN,
228*0b57cec5SDimitry Andric     EI_NSQRT,
229*0b57cec5SDimitry Andric     EI_FTZ,
230*0b57cec5SDimitry Andric     EI_FLDEXP,
231*0b57cec5SDimitry Andric     EI_CLASS,
232*0b57cec5SDimitry Andric     EI_RCBRT,
233*0b57cec5SDimitry Andric     EI_LAST_MANGLED =
234*0b57cec5SDimitry Andric         EI_RCBRT, /* The last library function with mangled name */
235*0b57cec5SDimitry Andric 
236*0b57cec5SDimitry Andric     // Library functions with unmangled name.
237*0b57cec5SDimitry Andric     EI_READ_PIPE_2,
238*0b57cec5SDimitry Andric     EI_READ_PIPE_4,
239*0b57cec5SDimitry Andric     EI_WRITE_PIPE_2,
240*0b57cec5SDimitry Andric     EI_WRITE_PIPE_4,
241*0b57cec5SDimitry Andric 
242*0b57cec5SDimitry Andric     EX_INTRINSICS_COUNT
243*0b57cec5SDimitry Andric   };
244*0b57cec5SDimitry Andric 
245*0b57cec5SDimitry Andric   enum ENamePrefix {
246*0b57cec5SDimitry Andric     NOPFX,
247*0b57cec5SDimitry Andric     NATIVE,
248*0b57cec5SDimitry Andric     HALF
249*0b57cec5SDimitry Andric   };
250*0b57cec5SDimitry Andric 
251*0b57cec5SDimitry Andric   enum EType {
252*0b57cec5SDimitry Andric     B8  = 1,
253*0b57cec5SDimitry Andric     B16 = 2,
254*0b57cec5SDimitry Andric     B32 = 3,
255*0b57cec5SDimitry Andric     B64 = 4,
256*0b57cec5SDimitry Andric     SIZE_MASK = 7,
257*0b57cec5SDimitry Andric     FLOAT = 0x10,
258*0b57cec5SDimitry Andric     INT   = 0x20,
259*0b57cec5SDimitry Andric     UINT  = 0x30,
260*0b57cec5SDimitry Andric     BASE_TYPE_MASK = 0x30,
261*0b57cec5SDimitry Andric     U8  =  UINT | B8,
262*0b57cec5SDimitry Andric     U16 =  UINT | B16,
263*0b57cec5SDimitry Andric     U32 =  UINT | B32,
264*0b57cec5SDimitry Andric     U64 =  UINT | B64,
265*0b57cec5SDimitry Andric     I8  =   INT | B8,
266*0b57cec5SDimitry Andric     I16 =   INT | B16,
267*0b57cec5SDimitry Andric     I32 =   INT | B32,
268*0b57cec5SDimitry Andric     I64 =   INT | B64,
269*0b57cec5SDimitry Andric     F16 = FLOAT | B16,
270*0b57cec5SDimitry Andric     F32 = FLOAT | B32,
271*0b57cec5SDimitry Andric     F64 = FLOAT | B64,
272*0b57cec5SDimitry Andric     IMG1DA = 0x80,
273*0b57cec5SDimitry Andric     IMG1DB,
274*0b57cec5SDimitry Andric     IMG2DA,
275*0b57cec5SDimitry Andric     IMG1D,
276*0b57cec5SDimitry Andric     IMG2D,
277*0b57cec5SDimitry Andric     IMG3D,
278*0b57cec5SDimitry Andric     SAMPLER,
279*0b57cec5SDimitry Andric     EVENT,
280*0b57cec5SDimitry Andric     DUMMY
281*0b57cec5SDimitry Andric   };
282*0b57cec5SDimitry Andric 
283*0b57cec5SDimitry Andric   enum EPtrKind {
284*0b57cec5SDimitry Andric     BYVALUE = 0,
285*0b57cec5SDimitry Andric     ADDR_SPACE = 0xF, // Address space takes value 0x1 ~ 0xF.
286*0b57cec5SDimitry Andric     CONST      = 0x10,
287*0b57cec5SDimitry Andric     VOLATILE   = 0x20
288*0b57cec5SDimitry Andric   };
289*0b57cec5SDimitry Andric 
290*0b57cec5SDimitry Andric   struct Param {
291*0b57cec5SDimitry Andric     unsigned char ArgType;
292*0b57cec5SDimitry Andric     unsigned char VectorSize;
293*0b57cec5SDimitry Andric     unsigned char PtrKind;
294*0b57cec5SDimitry Andric 
295*0b57cec5SDimitry Andric     unsigned char Reserved;
296*0b57cec5SDimitry Andric 
297*0b57cec5SDimitry Andric     void reset() {
298*0b57cec5SDimitry Andric       ArgType = 0;
299*0b57cec5SDimitry Andric       VectorSize = 1;
300*0b57cec5SDimitry Andric       PtrKind = 0;
301*0b57cec5SDimitry Andric     }
302*0b57cec5SDimitry Andric     Param() { reset(); }
303*0b57cec5SDimitry Andric 
304*0b57cec5SDimitry Andric     template <typename Stream>
305*0b57cec5SDimitry Andric     void mangleItanium(Stream& os);
306*0b57cec5SDimitry Andric   };
307*0b57cec5SDimitry Andric   static bool isMangled(EFuncId Id) {
308*0b57cec5SDimitry Andric     return static_cast<unsigned>(Id) <= static_cast<unsigned>(EI_LAST_MANGLED);
309*0b57cec5SDimitry Andric   }
310*0b57cec5SDimitry Andric 
311*0b57cec5SDimitry Andric   static unsigned getEPtrKindFromAddrSpace(unsigned AS) {
312*0b57cec5SDimitry Andric     assert(((AS + 1) & ~ADDR_SPACE) == 0);
313*0b57cec5SDimitry Andric     return AS + 1;
314*0b57cec5SDimitry Andric   }
315*0b57cec5SDimitry Andric 
316*0b57cec5SDimitry Andric   static unsigned getAddrSpaceFromEPtrKind(unsigned Kind) {
317*0b57cec5SDimitry Andric     Kind = Kind & ADDR_SPACE;
318*0b57cec5SDimitry Andric     assert(Kind >= 1);
319*0b57cec5SDimitry Andric     return Kind - 1;
320*0b57cec5SDimitry Andric   }
321*0b57cec5SDimitry Andric };
322*0b57cec5SDimitry Andric 
323*0b57cec5SDimitry Andric class AMDGPULibFuncImpl : public AMDGPULibFuncBase {
324*0b57cec5SDimitry Andric public:
325*0b57cec5SDimitry Andric   AMDGPULibFuncImpl() {}
326*0b57cec5SDimitry Andric   virtual ~AMDGPULibFuncImpl() {}
327*0b57cec5SDimitry Andric 
328*0b57cec5SDimitry Andric   /// Get unmangled name for mangled library function and name for unmangled
329*0b57cec5SDimitry Andric   /// library function.
330*0b57cec5SDimitry Andric   virtual std::string getName() const = 0;
331*0b57cec5SDimitry Andric   virtual unsigned getNumArgs() const = 0;
332*0b57cec5SDimitry Andric   EFuncId getId() const { return FuncId; }
333*0b57cec5SDimitry Andric   ENamePrefix getPrefix() const { return FKind; }
334*0b57cec5SDimitry Andric 
335*0b57cec5SDimitry Andric   bool isMangled() const { return AMDGPULibFuncBase::isMangled(FuncId); }
336*0b57cec5SDimitry Andric 
337*0b57cec5SDimitry Andric   void setId(EFuncId id) { FuncId = id; }
338*0b57cec5SDimitry Andric   virtual bool parseFuncName(StringRef &mangledName) = 0;
339*0b57cec5SDimitry Andric 
340*0b57cec5SDimitry Andric   /// \return The mangled function name for mangled library functions
341*0b57cec5SDimitry Andric   /// and unmangled function name for unmangled library functions.
342*0b57cec5SDimitry Andric   virtual std::string mangle() const = 0;
343*0b57cec5SDimitry Andric 
344*0b57cec5SDimitry Andric   void setName(StringRef N) { Name = N; }
345*0b57cec5SDimitry Andric   void setPrefix(ENamePrefix pfx) { FKind = pfx; }
346*0b57cec5SDimitry Andric 
347*0b57cec5SDimitry Andric   virtual FunctionType *getFunctionType(Module &M) const = 0;
348*0b57cec5SDimitry Andric 
349*0b57cec5SDimitry Andric protected:
350*0b57cec5SDimitry Andric   EFuncId FuncId;
351*0b57cec5SDimitry Andric   std::string Name;
352*0b57cec5SDimitry Andric   ENamePrefix FKind;
353*0b57cec5SDimitry Andric };
354*0b57cec5SDimitry Andric 
355*0b57cec5SDimitry Andric /// Wrapper class for AMDGPULIbFuncImpl
356*0b57cec5SDimitry Andric class AMDGPULibFunc : public AMDGPULibFuncBase {
357*0b57cec5SDimitry Andric public:
358*0b57cec5SDimitry Andric   explicit AMDGPULibFunc() : Impl(std::unique_ptr<AMDGPULibFuncImpl>()) {}
359*0b57cec5SDimitry Andric   AMDGPULibFunc(const AMDGPULibFunc &F);
360*0b57cec5SDimitry Andric   /// Clone a mangled library func with the Id \p Id and argument info from \p
361*0b57cec5SDimitry Andric   /// CopyFrom.
362*0b57cec5SDimitry Andric   explicit AMDGPULibFunc(EFuncId Id, const AMDGPULibFunc &CopyFrom);
363*0b57cec5SDimitry Andric   /// Construct an unmangled library function on the fly.
364*0b57cec5SDimitry Andric   explicit AMDGPULibFunc(StringRef FName, FunctionType *FT);
365*0b57cec5SDimitry Andric 
366*0b57cec5SDimitry Andric   AMDGPULibFunc &operator=(const AMDGPULibFunc &F);
367*0b57cec5SDimitry Andric 
368*0b57cec5SDimitry Andric   /// Get unmangled name for mangled library function and name for unmangled
369*0b57cec5SDimitry Andric   /// library function.
370*0b57cec5SDimitry Andric   std::string getName() const { return Impl->getName(); }
371*0b57cec5SDimitry Andric   unsigned getNumArgs() const { return Impl->getNumArgs(); }
372*0b57cec5SDimitry Andric   EFuncId getId() const { return Impl->getId(); }
373*0b57cec5SDimitry Andric   ENamePrefix getPrefix() const { return Impl->getPrefix(); }
374*0b57cec5SDimitry Andric   /// Get leading parameters for mangled lib functions.
375*0b57cec5SDimitry Andric   Param *getLeads();
376*0b57cec5SDimitry Andric   const Param *getLeads() const;
377*0b57cec5SDimitry Andric 
378*0b57cec5SDimitry Andric   bool isMangled() const { return Impl->isMangled(); }
379*0b57cec5SDimitry Andric   void setId(EFuncId Id) { Impl->setId(Id); }
380*0b57cec5SDimitry Andric   bool parseFuncName(StringRef &MangledName) {
381*0b57cec5SDimitry Andric     return Impl->parseFuncName(MangledName);
382*0b57cec5SDimitry Andric   }
383*0b57cec5SDimitry Andric 
384*0b57cec5SDimitry Andric   /// \return The mangled function name for mangled library functions
385*0b57cec5SDimitry Andric   /// and unmangled function name for unmangled library functions.
386*0b57cec5SDimitry Andric   std::string mangle() const { return Impl->mangle(); }
387*0b57cec5SDimitry Andric 
388*0b57cec5SDimitry Andric   void setName(StringRef N) { Impl->setName(N); }
389*0b57cec5SDimitry Andric   void setPrefix(ENamePrefix PFX) { Impl->setPrefix(PFX); }
390*0b57cec5SDimitry Andric 
391*0b57cec5SDimitry Andric   FunctionType *getFunctionType(Module &M) const {
392*0b57cec5SDimitry Andric     return Impl->getFunctionType(M);
393*0b57cec5SDimitry Andric   }
394*0b57cec5SDimitry Andric   static Function *getFunction(llvm::Module *M, const AMDGPULibFunc &fInfo);
395*0b57cec5SDimitry Andric 
396*0b57cec5SDimitry Andric   static FunctionCallee getOrInsertFunction(llvm::Module *M,
397*0b57cec5SDimitry Andric                                             const AMDGPULibFunc &fInfo);
398*0b57cec5SDimitry Andric   static bool parse(StringRef MangledName, AMDGPULibFunc &Ptr);
399*0b57cec5SDimitry Andric 
400*0b57cec5SDimitry Andric private:
401*0b57cec5SDimitry Andric   /// Initialize as a mangled library function.
402*0b57cec5SDimitry Andric   void initMangled();
403*0b57cec5SDimitry Andric   std::unique_ptr<AMDGPULibFuncImpl> Impl;
404*0b57cec5SDimitry Andric };
405*0b57cec5SDimitry Andric 
406*0b57cec5SDimitry Andric class AMDGPUMangledLibFunc : public AMDGPULibFuncImpl {
407*0b57cec5SDimitry Andric public:
408*0b57cec5SDimitry Andric   Param Leads[2];
409*0b57cec5SDimitry Andric 
410*0b57cec5SDimitry Andric   explicit AMDGPUMangledLibFunc();
411*0b57cec5SDimitry Andric   explicit AMDGPUMangledLibFunc(EFuncId id,
412*0b57cec5SDimitry Andric                                 const AMDGPUMangledLibFunc &copyFrom);
413*0b57cec5SDimitry Andric 
414*0b57cec5SDimitry Andric   std::string getName() const override;
415*0b57cec5SDimitry Andric   unsigned getNumArgs() const override;
416*0b57cec5SDimitry Andric   FunctionType *getFunctionType(Module &M) const override;
417*0b57cec5SDimitry Andric   static StringRef getUnmangledName(StringRef MangledName);
418*0b57cec5SDimitry Andric 
419*0b57cec5SDimitry Andric   bool parseFuncName(StringRef &mangledName) override;
420*0b57cec5SDimitry Andric 
421*0b57cec5SDimitry Andric   // Methods for support type inquiry through isa, cast, and dyn_cast:
422*0b57cec5SDimitry Andric   static bool classof(const AMDGPULibFuncImpl *F) { return F->isMangled(); }
423*0b57cec5SDimitry Andric 
424*0b57cec5SDimitry Andric   std::string mangle() const override;
425*0b57cec5SDimitry Andric 
426*0b57cec5SDimitry Andric private:
427*0b57cec5SDimitry Andric   std::string mangleNameItanium() const;
428*0b57cec5SDimitry Andric 
429*0b57cec5SDimitry Andric   std::string mangleName(StringRef Name) const;
430*0b57cec5SDimitry Andric   bool parseUnmangledName(StringRef MangledName);
431*0b57cec5SDimitry Andric 
432*0b57cec5SDimitry Andric   template <typename Stream> void writeName(Stream &OS) const;
433*0b57cec5SDimitry Andric };
434*0b57cec5SDimitry Andric 
435*0b57cec5SDimitry Andric class AMDGPUUnmangledLibFunc : public AMDGPULibFuncImpl {
436*0b57cec5SDimitry Andric   FunctionType *FuncTy;
437*0b57cec5SDimitry Andric 
438*0b57cec5SDimitry Andric public:
439*0b57cec5SDimitry Andric   explicit AMDGPUUnmangledLibFunc();
440*0b57cec5SDimitry Andric   explicit AMDGPUUnmangledLibFunc(StringRef FName, FunctionType *FT) {
441*0b57cec5SDimitry Andric     Name = FName;
442*0b57cec5SDimitry Andric     FuncTy = FT;
443*0b57cec5SDimitry Andric   }
444*0b57cec5SDimitry Andric   std::string getName() const override { return Name; }
445*0b57cec5SDimitry Andric   unsigned getNumArgs() const override;
446*0b57cec5SDimitry Andric   FunctionType *getFunctionType(Module &M) const override { return FuncTy; }
447*0b57cec5SDimitry Andric 
448*0b57cec5SDimitry Andric   bool parseFuncName(StringRef &Name) override;
449*0b57cec5SDimitry Andric 
450*0b57cec5SDimitry Andric   // Methods for support type inquiry through isa, cast, and dyn_cast:
451*0b57cec5SDimitry Andric   static bool classof(const AMDGPULibFuncImpl *F) { return !F->isMangled(); }
452*0b57cec5SDimitry Andric 
453*0b57cec5SDimitry Andric   std::string mangle() const override { return Name; }
454*0b57cec5SDimitry Andric 
455*0b57cec5SDimitry Andric   void setFunctionType(FunctionType *FT) { FuncTy = FT; }
456*0b57cec5SDimitry Andric };
457*0b57cec5SDimitry Andric }
458*0b57cec5SDimitry Andric #endif // _AMDGPU_LIBFUNC_H_
459