xref: /llvm-project/clang/include/clang/Basic/TargetBuiltins.h (revision 7e22180c20fa3b4e0add41ad620d2eaac2b47fcc)
1 //===--- TargetBuiltins.h - Target specific builtin IDs ---------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// Enumerates target-specific builtins in their own namespaces within
11 /// namespace ::clang.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_BASIC_TARGETBUILTINS_H
16 #define LLVM_CLANG_BASIC_TARGETBUILTINS_H
17 
18 #include <algorithm>
19 #include <stdint.h>
20 #include "clang/Basic/Builtins.h"
21 #include "llvm/Support/MathExtras.h"
22 #undef PPC
23 
24 namespace clang {
25 
26   namespace NEON {
27   enum {
28     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
29 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
30 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID,
31 #include "clang/Basic/BuiltinsNEON.def"
32     FirstTSBuiltin
33   };
34   }
35 
36   /// ARM builtins
37   namespace ARM {
38     enum {
39       LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
40       LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
41 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
42 #include "clang/Basic/BuiltinsARM.def"
43       LastTSBuiltin
44     };
45   }
46 
47   namespace SVE {
48   enum {
49     LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
50 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
51 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID,
52 #include "clang/Basic/BuiltinsSVE.def"
53     FirstTSBuiltin,
54   };
55   }
56 
57   namespace SME {
58   enum {
59     LastSVEBuiltin = SVE::FirstTSBuiltin - 1,
60 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
61 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BI##ID,
62 #include "clang/Basic/BuiltinsSME.def"
63     FirstTSBuiltin,
64   };
65   }
66 
67   /// AArch64 builtins
68   namespace AArch64 {
69   enum {
70     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
71     LastNEONBuiltin = NEON::FirstTSBuiltin - 1,
72     FirstSVEBuiltin = NEON::FirstTSBuiltin,
73     LastSVEBuiltin = SVE::FirstTSBuiltin - 1,
74     FirstSMEBuiltin = SVE::FirstTSBuiltin,
75     LastSMEBuiltin = SME::FirstTSBuiltin - 1,
76   #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
77   #include "clang/Basic/BuiltinsAArch64.def"
78     LastTSBuiltin
79   };
80   }
81 
82   /// BPF builtins
83   namespace BPF {
84   enum {
85     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
86   #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
87   #include "clang/Basic/BuiltinsBPF.inc"
88     LastTSBuiltin
89   };
90   }
91 
92   /// PPC builtins
93   namespace PPC {
94     enum {
95         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
96 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
97 #include "clang/Basic/BuiltinsPPC.def"
98         LastTSBuiltin
99     };
100   }
101 
102   /// NVPTX builtins
103   namespace NVPTX {
104   enum {
105     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
106 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
107 #include "clang/Basic/BuiltinsNVPTX.inc"
108     LastTSBuiltin
109   };
110   }
111 
112   /// AMDGPU builtins
113   namespace AMDGPU {
114   enum {
115     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
116   #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
117   #include "clang/Basic/BuiltinsAMDGPU.def"
118     LastTSBuiltin
119   };
120   }
121 
122   /// SPIRV builtins
123   namespace SPIRV {
124   enum {
125     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
126 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
127 #include "clang/Basic/BuiltinsSPIRV.inc"
128     LastTSBuiltin
129   };
130   } // namespace SPIRV
131 
132   /// X86 builtins
133   namespace X86 {
134   enum {
135     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
136 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
137 #include "clang/Basic/BuiltinsX86.inc"
138     FirstX86_64Builtin,
139     LastX86CommonBuiltin = FirstX86_64Builtin - 1,
140 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
141 #include "clang/Basic/BuiltinsX86_64.inc"
142     LastTSBuiltin
143   };
144   }
145 
146   /// VE builtins
147   namespace VE {
148   enum {
149     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
150 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
151 #include "clang/Basic/BuiltinsVE.def"
152     LastTSBuiltin
153   };
154   }
155 
156   namespace RISCVVector {
157   enum {
158     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
159 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
160 #include "clang/Basic/BuiltinsRISCVVector.def"
161     FirstTSBuiltin,
162   };
163   }
164 
165   /// RISCV builtins
166   namespace RISCV {
167   enum {
168     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
169     FirstRVVBuiltin = clang::Builtin::FirstTSBuiltin,
170     LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1,
171 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
172 #include "clang/Basic/BuiltinsRISCV.inc"
173     LastTSBuiltin
174   };
175   } // namespace RISCV
176 
177   /// LoongArch builtins
178   namespace LoongArch {
179   enum {
180     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
181 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
182 #include "clang/Basic/BuiltinsLoongArch.def"
183     LastTSBuiltin
184   };
185   } // namespace LoongArch
186 
187   /// Flags to identify the types for overloaded Neon builtins.
188   ///
189   /// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
190   class NeonTypeFlags {
191     enum {
192       EltTypeMask = 0xf,
193       UnsignedFlag = 0x10,
194       QuadFlag = 0x20
195     };
196     uint32_t Flags;
197 
198   public:
199     enum EltType {
200       Int8,
201       Int16,
202       Int32,
203       Int64,
204       Poly8,
205       Poly16,
206       Poly64,
207       Poly128,
208       Float16,
209       Float32,
210       Float64,
211       BFloat16,
212       MFloat8
213     };
214 
215     NeonTypeFlags(unsigned F) : Flags(F) {}
216     NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
217       if (IsUnsigned)
218         Flags |= UnsignedFlag;
219       if (IsQuad)
220         Flags |= QuadFlag;
221     }
222 
223     EltType getEltType() const { return (EltType)(Flags & EltTypeMask); }
224     bool isPoly() const {
225       EltType ET = getEltType();
226       return ET == Poly8 || ET == Poly16 || ET == Poly64;
227     }
228     bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; }
229     bool isQuad() const { return (Flags & QuadFlag) != 0; }
230     unsigned getEltSizeInBits() const {
231       switch (getEltType()) {
232       case Int8:
233       case Poly8:
234       case MFloat8:
235         return 8;
236       case Int16:
237       case Float16:
238       case Poly16:
239       case BFloat16:
240         return 16;
241       case Int32:
242       case Float32:
243         return 32;
244       case Int64:
245       case Float64:
246       case Poly64:
247         return 64;
248       case Poly128:
249         return 128;
250       }
251       llvm_unreachable("Invalid NeonTypeFlag!");
252     }
253   };
254 
255   // Shared between SVE/SME and NEON
256   enum ImmCheckType {
257 #define LLVM_GET_ARM_INTRIN_IMMCHECKTYPES
258 #include "clang/Basic/arm_immcheck_types.inc"
259 #undef LLVM_GET_ARM_INTRIN_IMMCHECKTYPES
260   };
261 
262   /// Flags to identify the types for overloaded SVE builtins.
263   class SVETypeFlags {
264     uint64_t Flags;
265     unsigned EltTypeShift;
266     unsigned MemEltTypeShift;
267     unsigned MergeTypeShift;
268     unsigned SplatOperandMaskShift;
269 
270   public:
271 #define LLVM_GET_SVE_TYPEFLAGS
272 #include "clang/Basic/arm_sve_typeflags.inc"
273 #undef LLVM_GET_SVE_TYPEFLAGS
274 
275     enum EltType {
276 #define LLVM_GET_SVE_ELTTYPES
277 #include "clang/Basic/arm_sve_typeflags.inc"
278 #undef LLVM_GET_SVE_ELTTYPES
279     };
280 
281     enum MemEltType {
282 #define LLVM_GET_SVE_MEMELTTYPES
283 #include "clang/Basic/arm_sve_typeflags.inc"
284 #undef LLVM_GET_SVE_MEMELTTYPES
285     };
286 
287     enum MergeType {
288 #define LLVM_GET_SVE_MERGETYPES
289 #include "clang/Basic/arm_sve_typeflags.inc"
290 #undef LLVM_GET_SVE_MERGETYPES
291     };
292 
293     SVETypeFlags(uint64_t F) : Flags(F) {
294       EltTypeShift = llvm::countr_zero(EltTypeMask);
295       MemEltTypeShift = llvm::countr_zero(MemEltTypeMask);
296       MergeTypeShift = llvm::countr_zero(MergeTypeMask);
297       SplatOperandMaskShift = llvm::countr_zero(SplatOperandMask);
298     }
299 
300     EltType getEltType() const {
301       return (EltType)((Flags & EltTypeMask) >> EltTypeShift);
302     }
303 
304     MemEltType getMemEltType() const {
305       return (MemEltType)((Flags & MemEltTypeMask) >> MemEltTypeShift);
306     }
307 
308     MergeType getMergeType() const {
309       return (MergeType)((Flags & MergeTypeMask) >> MergeTypeShift);
310     }
311 
312     unsigned getSplatOperand() const {
313       return ((Flags & SplatOperandMask) >> SplatOperandMaskShift) - 1;
314     }
315 
316     bool hasSplatOperand() const {
317       return Flags & SplatOperandMask;
318     }
319 
320     bool isLoad() const { return Flags & IsLoad; }
321     bool isStore() const { return Flags & IsStore; }
322     bool isGatherLoad() const { return Flags & IsGatherLoad; }
323     bool isScatterStore() const { return Flags & IsScatterStore; }
324     bool isStructLoad() const { return Flags & IsStructLoad; }
325     bool isStructStore() const { return Flags & IsStructStore; }
326     bool isZExtReturn() const { return Flags & IsZExtReturn; }
327     bool isByteIndexed() const { return Flags & IsByteIndexed; }
328     bool isOverloadNone() const { return Flags & IsOverloadNone; }
329     bool isOverloadWhileOrMultiVecCvt() const {
330       return Flags & IsOverloadWhileOrMultiVecCvt;
331     }
332     bool isOverloadDefault() const { return !(Flags & OverloadKindMask); }
333     bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; }
334     bool isOverloadCvt() const { return Flags & IsOverloadCvt; }
335     bool isPrefetch() const { return Flags & IsPrefetch; }
336     bool isReverseCompare() const { return Flags & ReverseCompare; }
337     bool isAppendSVALL() const { return Flags & IsAppendSVALL; }
338     bool isInsertOp1SVALL() const { return Flags & IsInsertOp1SVALL; }
339     bool isGatherPrefetch() const { return Flags & IsGatherPrefetch; }
340     bool isReverseUSDOT() const { return Flags & ReverseUSDOT; }
341     bool isReverseMergeAnyBinOp() const { return Flags & ReverseMergeAnyBinOp; }
342     bool isReverseMergeAnyAccOp() const { return Flags & ReverseMergeAnyAccOp; }
343     bool isUndef() const { return Flags & IsUndef; }
344     bool isTupleCreate() const { return Flags & IsTupleCreate; }
345     bool isTupleGet() const { return Flags & IsTupleGet; }
346     bool isTupleSet() const { return Flags & IsTupleSet; }
347     bool isReadZA() const { return Flags & IsReadZA; }
348     bool isWriteZA() const { return Flags & IsWriteZA; }
349     bool setsFPMR() const { return Flags & SetsFPMR; }
350     bool isReductionQV() const { return Flags & IsReductionQV; }
351     uint64_t getBits() const { return Flags; }
352     bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }
353   };
354 
355   /// Hexagon builtins
356   namespace Hexagon {
357   enum {
358     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
359 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
360 #include "clang/Basic/BuiltinsHexagon.inc"
361     LastTSBuiltin
362   };
363   }
364 
365   /// MIPS builtins
366   namespace Mips {
367     enum {
368         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
369 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
370 #include "clang/Basic/BuiltinsMips.def"
371         LastTSBuiltin
372     };
373   }
374 
375   /// XCore builtins
376   namespace XCore {
377     enum {
378         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
379 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
380 #include "clang/Basic/BuiltinsXCore.def"
381         LastTSBuiltin
382     };
383   }
384 
385   /// SystemZ builtins
386   namespace SystemZ {
387     enum {
388         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
389 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
390 #include "clang/Basic/BuiltinsSystemZ.def"
391         LastTSBuiltin
392     };
393   }
394 
395   /// WebAssembly builtins
396   namespace WebAssembly {
397     enum {
398       LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
399 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
400 #include "clang/Basic/BuiltinsWebAssembly.def"
401       LastTSBuiltin
402     };
403   }
404 
405   static constexpr uint64_t LargestBuiltinID = std::max<uint64_t>(
406       {ARM::LastTSBuiltin, AArch64::LastTSBuiltin, BPF::LastTSBuiltin,
407        PPC::LastTSBuiltin, NVPTX::LastTSBuiltin, AMDGPU::LastTSBuiltin,
408        X86::LastTSBuiltin, VE::LastTSBuiltin, RISCV::LastTSBuiltin,
409        Hexagon::LastTSBuiltin, Mips::LastTSBuiltin, XCore::LastTSBuiltin,
410        SystemZ::LastTSBuiltin, WebAssembly::LastTSBuiltin});
411 
412 } // end namespace clang.
413 
414 #endif
415