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.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.inc" 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