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 
NeonTypeFlags(unsigned F)204     NeonTypeFlags(unsigned F) : Flags(F) {}
NeonTypeFlags(EltType ET,bool IsUnsigned,bool IsQuad)205     NeonTypeFlags(EltType ET, bool IsUnsigned, bool IsQuad) : Flags(ET) {
206       if (IsUnsigned)
207         Flags |= UnsignedFlag;
208       if (IsQuad)
209         Flags |= QuadFlag;
210     }
211 
getEltType()212     EltType getEltType() const { return (EltType)(Flags & EltTypeMask); }
isPoly()213     bool isPoly() const {
214       EltType ET = getEltType();
215       return ET == Poly8 || ET == Poly16 || ET == Poly64;
216     }
isUnsigned()217     bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; }
isQuad()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 
SVETypeFlags(uint64_t F)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 
getEltType()265     EltType getEltType() const {
266       return (EltType)((Flags & EltTypeMask) >> EltTypeShift);
267     }
268 
getMemEltType()269     MemEltType getMemEltType() const {
270       return (MemEltType)((Flags & MemEltTypeMask) >> MemEltTypeShift);
271     }
272 
getMergeType()273     MergeType getMergeType() const {
274       return (MergeType)((Flags & MergeTypeMask) >> MergeTypeShift);
275     }
276 
getSplatOperand()277     unsigned getSplatOperand() const {
278       return ((Flags & SplatOperandMask) >> SplatOperandMaskShift) - 1;
279     }
280 
hasSplatOperand()281     bool hasSplatOperand() const {
282       return Flags & SplatOperandMask;
283     }
284 
isLoad()285     bool isLoad() const { return Flags & IsLoad; }
isStore()286     bool isStore() const { return Flags & IsStore; }
isGatherLoad()287     bool isGatherLoad() const { return Flags & IsGatherLoad; }
isScatterStore()288     bool isScatterStore() const { return Flags & IsScatterStore; }
isStructLoad()289     bool isStructLoad() const { return Flags & IsStructLoad; }
isStructStore()290     bool isStructStore() const { return Flags & IsStructStore; }
isZExtReturn()291     bool isZExtReturn() const { return Flags & IsZExtReturn; }
isByteIndexed()292     bool isByteIndexed() const { return Flags & IsByteIndexed; }
isOverloadNone()293     bool isOverloadNone() const { return Flags & IsOverloadNone; }
isOverloadWhileOrMultiVecCvt()294     bool isOverloadWhileOrMultiVecCvt() const {
295       return Flags & IsOverloadWhileOrMultiVecCvt;
296     }
isOverloadDefault()297     bool isOverloadDefault() const { return !(Flags & OverloadKindMask); }
isOverloadWhileRW()298     bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; }
isOverloadCvt()299     bool isOverloadCvt() const { return Flags & IsOverloadCvt; }
isPrefetch()300     bool isPrefetch() const { return Flags & IsPrefetch; }
isReverseCompare()301     bool isReverseCompare() const { return Flags & ReverseCompare; }
isAppendSVALL()302     bool isAppendSVALL() const { return Flags & IsAppendSVALL; }
isInsertOp1SVALL()303     bool isInsertOp1SVALL() const { return Flags & IsInsertOp1SVALL; }
isGatherPrefetch()304     bool isGatherPrefetch() const { return Flags & IsGatherPrefetch; }
isReverseUSDOT()305     bool isReverseUSDOT() const { return Flags & ReverseUSDOT; }
isReverseMergeAnyBinOp()306     bool isReverseMergeAnyBinOp() const { return Flags & ReverseMergeAnyBinOp; }
isReverseMergeAnyAccOp()307     bool isReverseMergeAnyAccOp() const { return Flags & ReverseMergeAnyAccOp; }
isUndef()308     bool isUndef() const { return Flags & IsUndef; }
isTupleCreate()309     bool isTupleCreate() const { return Flags & IsTupleCreate; }
isTupleGet()310     bool isTupleGet() const { return Flags & IsTupleGet; }
isTupleSet()311     bool isTupleSet() const { return Flags & IsTupleSet; }
isReadZA()312     bool isReadZA() const { return Flags & IsReadZA; }
isWriteZA()313     bool isWriteZA() const { return Flags & IsWriteZA; }
isReductionQV()314     bool isReductionQV() const { return Flags & IsReductionQV; }
getBits()315     uint64_t getBits() const { return Flags; }
isFlagSet(uint64_t Flag)316     bool isFlagSet(uint64_t Flag) const { return Flags & Flag; }
317   };
318 
319   /// Hexagon builtins
320   namespace Hexagon {
321     enum {
322         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
323 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
324 #include "clang/Basic/BuiltinsHexagon.def"
325         LastTSBuiltin
326     };
327   }
328 
329   /// MIPS builtins
330   namespace Mips {
331     enum {
332         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
333 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
334 #include "clang/Basic/BuiltinsMips.def"
335         LastTSBuiltin
336     };
337   }
338 
339   /// XCore builtins
340   namespace XCore {
341     enum {
342         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
343 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
344 #include "clang/Basic/BuiltinsXCore.def"
345         LastTSBuiltin
346     };
347   }
348 
349   /// SystemZ builtins
350   namespace SystemZ {
351     enum {
352         LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
353 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
354 #include "clang/Basic/BuiltinsSystemZ.def"
355         LastTSBuiltin
356     };
357   }
358 
359   /// WebAssembly builtins
360   namespace WebAssembly {
361     enum {
362       LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1,
363 #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
364 #include "clang/Basic/BuiltinsWebAssembly.def"
365       LastTSBuiltin
366     };
367   }
368 
369   static constexpr uint64_t LargestBuiltinID = std::max<uint64_t>(
370       {ARM::LastTSBuiltin, AArch64::LastTSBuiltin, BPF::LastTSBuiltin,
371        PPC::LastTSBuiltin, NVPTX::LastTSBuiltin, AMDGPU::LastTSBuiltin,
372        X86::LastTSBuiltin, VE::LastTSBuiltin, RISCV::LastTSBuiltin,
373        Hexagon::LastTSBuiltin, Mips::LastTSBuiltin, XCore::LastTSBuiltin,
374        SystemZ::LastTSBuiltin, WebAssembly::LastTSBuiltin});
375 
376 } // end namespace clang.
377 
378 #endif
379