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.def"
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.def"
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   /// X86 builtins
123   namespace X86 {
124   enum {
125     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
126 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
127 #include "clang/Basic/BuiltinsX86.def"
128     FirstX86_64Builtin,
129     LastX86CommonBuiltin = FirstX86_64Builtin - 1,
130 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
131 #include "clang/Basic/BuiltinsX86_64.def"
132     LastTSBuiltin
133   };
134   }
135 
136   /// VE builtins
137   namespace VE {
138   enum {
139     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
140 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
141 #include "clang/Basic/BuiltinsVE.def"
142     LastTSBuiltin
143   };
144   }
145 
146   namespace RISCVVector {
147   enum {
148     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
149 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
150 #include "clang/Basic/BuiltinsRISCVVector.def"
151     FirstTSBuiltin,
152   };
153   }
154 
155   /// RISCV builtins
156   namespace RISCV {
157   enum {
158     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
159     FirstRVVBuiltin = clang::Builtin::FirstTSBuiltin,
160     LastRVVBuiltin = RISCVVector::FirstTSBuiltin - 1,
161 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
162 #include "clang/Basic/BuiltinsRISCV.def"
163     LastTSBuiltin
164   };
165   } // namespace RISCV
166 
167   /// LoongArch builtins
168   namespace LoongArch {
169   enum {
170     LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1,
171 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
172 #include "clang/Basic/BuiltinsLoongArch.def"
173     LastTSBuiltin
174   };
175   } // namespace LoongArch
176 
177   /// Flags to identify the types for overloaded Neon builtins.
178   ///
179   /// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h.
180   class NeonTypeFlags {
181     enum {
182       EltTypeMask = 0xf,
183       UnsignedFlag = 0x10,
184       QuadFlag = 0x20
185     };
186     uint32_t Flags;
187 
188   public:
189     enum EltType {
190       Int8,
191       Int16,
192       Int32,
193       Int64,
194       Poly8,
195       Poly16,
196       Poly64,
197       Poly128,
198       Float16,
199       Float32,
200       Float64,
201       BFloat16
202     };
203 
204     NeonTypeFlags(unsigned F) : Flags(F) {}
205     NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
206       if (IsUnsigned)
207         Flags |= UnsignedFlag;
208       if (IsQuad)
209         Flags |= QuadFlag;
210     }
211 
212     EltType getEltType() const { return (EltType)(Flags & EltTypeMask); }
213     bool isPoly() const {
214       EltType ET = getEltType();
215       return ET == Poly8 || ET == Poly16 || ET == Poly64;
216     }
217     bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; }
218     bool isQuad() const { return (Flags & QuadFlag) != 0; }
219   };
220 
221   /// Flags to identify the types for overloaded SVE builtins.
222   class SVETypeFlags {
223     uint64_t Flags;
224     unsigned EltTypeShift;
225     unsigned MemEltTypeShift;
226     unsigned MergeTypeShift;
227     unsigned SplatOperandMaskShift;
228 
229   public:
230 #define LLVM_GET_SVE_TYPEFLAGS
231 #include "clang/Basic/arm_sve_typeflags.inc"
232 #undef LLVM_GET_SVE_TYPEFLAGS
233 
234     enum EltType {
235 #define LLVM_GET_SVE_ELTTYPES
236 #include "clang/Basic/arm_sve_typeflags.inc"
237 #undef LLVM_GET_SVE_ELTTYPES
238     };
239 
240     enum MemEltType {
241 #define LLVM_GET_SVE_MEMELTTYPES
242 #include "clang/Basic/arm_sve_typeflags.inc"
243 #undef LLVM_GET_SVE_MEMELTTYPES
244     };
245 
246     enum MergeType {
247 #define LLVM_GET_SVE_MERGETYPES
248 #include "clang/Basic/arm_sve_typeflags.inc"
249 #undef LLVM_GET_SVE_MERGETYPES
250     };
251 
252     enum ImmCheckType {
253 #define LLVM_GET_SVE_IMMCHECKTYPES
254 #include "clang/Basic/arm_sve_typeflags.inc"
255 #undef LLVM_GET_SVE_IMMCHECKTYPES
256     };
257 
258     SVETypeFlags(uint64_t F) : Flags(F) {
259       EltTypeShift = llvm::countr_zero(EltTypeMask);
260       MemEltTypeShift = llvm::countr_zero(MemEltTypeMask);
261       MergeTypeShift = llvm::countr_zero(MergeTypeMask);
262       SplatOperandMaskShift = llvm::countr_zero(SplatOperandMask);
263     }
264 
265     EltType getEltType() const {
266       return (EltType)((Flags & EltTypeMask) >> EltTypeShift);
267     }
268 
269     MemEltType getMemEltType() const {
270       return (MemEltType)((Flags & MemEltTypeMask) >> MemEltTypeShift);
271     }
272 
273     MergeType getMergeType() const {
274       return (MergeType)((Flags & MergeTypeMask) >> MergeTypeShift);
275     }
276 
277     unsigned getSplatOperand() const {
278       return ((Flags & SplatOperandMask) >> SplatOperandMaskShift) - 1;
279     }
280 
281     bool hasSplatOperand() const {
282       return Flags & SplatOperandMask;
283     }
284 
285     bool isLoad() const { return Flags & IsLoad; }
286     bool isStore() const { return Flags & IsStore; }
287     bool isGatherLoad() const { return Flags & IsGatherLoad; }
288     bool isScatterStore() const { return Flags & IsScatterStore; }
289     bool isStructLoad() const { return Flags & IsStructLoad; }
290     bool isStructStore() const { return Flags & IsStructStore; }
291     bool isZExtReturn() const { return Flags & IsZExtReturn; }
292     bool isByteIndexed() const { return Flags & IsByteIndexed; }
293     bool isOverloadNone() const { return Flags & IsOverloadNone; }
294     bool isOverloadWhile() const { return Flags & IsOverloadWhile; }
295     bool isOverloadDefault() const { return !(Flags & OverloadKindMask); }
296     bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; }
297     bool isOverloadCvt() const { return Flags & IsOverloadCvt; }
298     bool isPrefetch() const { return Flags & IsPrefetch; }
299     bool isReverseCompare() const { return Flags & ReverseCompare; }
300     bool isAppendSVALL() const { return Flags & IsAppendSVALL; }
301     bool isInsertOp1SVALL() const { return Flags & IsInsertOp1SVALL; }
302     bool isGatherPrefetch() const { return Flags & IsGatherPrefetch; }
303     bool isReverseUSDOT() const { return Flags & ReverseUSDOT; }
304     bool isReverseMergeAnyBinOp() const { return Flags & ReverseMergeAnyBinOp; }
305     bool isReverseMergeAnyAccOp() const { return Flags & ReverseMergeAnyAccOp; }
306     bool isUndef() const { return Flags & IsUndef; }
307     bool isTupleCreate() const { return Flags & IsTupleCreate; }
308     bool isTupleGet() const { return Flags & IsTupleGet; }
309     bool isTupleSet() const { return Flags & IsTupleSet; }
310     bool isReadZA() const { return Flags & IsReadZA; }
311     bool isWriteZA() const { return Flags & IsWriteZA; }
312 
313     uint64_t getBits() const { return Flags; }
314     bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }
315   };
316 
317   /// Hexagon builtins
318   namespace Hexagon {
319     enum {
320         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
321 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
322 #include "clang/Basic/BuiltinsHexagon.def"
323         LastTSBuiltin
324     };
325   }
326 
327   /// MIPS builtins
328   namespace Mips {
329     enum {
330         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
331 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
332 #include "clang/Basic/BuiltinsMips.def"
333         LastTSBuiltin
334     };
335   }
336 
337   /// XCore builtins
338   namespace XCore {
339     enum {
340         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
341 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
342 #include "clang/Basic/BuiltinsXCore.def"
343         LastTSBuiltin
344     };
345   }
346 
347   /// SystemZ builtins
348   namespace SystemZ {
349     enum {
350         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
351 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
352 #include "clang/Basic/BuiltinsSystemZ.def"
353         LastTSBuiltin
354     };
355   }
356 
357   /// WebAssembly builtins
358   namespace WebAssembly {
359     enum {
360       LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
361 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
362 #include "clang/Basic/BuiltinsWebAssembly.def"
363       LastTSBuiltin
364     };
365   }
366 
367   static constexpr uint64_t LargestBuiltinID = std::max<uint64_t>(
368       {ARM::LastTSBuiltin, AArch64::LastTSBuiltin, BPF::LastTSBuiltin,
369        PPC::LastTSBuiltin, NVPTX::LastTSBuiltin, AMDGPU::LastTSBuiltin,
370        X86::LastTSBuiltin, VE::LastTSBuiltin, RISCV::LastTSBuiltin,
371        Hexagon::LastTSBuiltin, Mips::LastTSBuiltin, XCore::LastTSBuiltin,
372        SystemZ::LastTSBuiltin, WebAssembly::LastTSBuiltin});
373 
374 } // end namespace clang.
375 
376 #endif
377