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