1349cc55cSDimitry Andric //===--- SPIR.h - Declare SPIR and SPIR-V target feature support *- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 9349cc55cSDimitry Andric // This file declares SPIR and SPIR-V TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H 150b57cec5SDimitry Andric 1606c3fb27SDimitry Andric #include "Targets.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 180b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 207a6dacacSDimitry Andric #include "llvm/Support/VersionTuple.h" 2106c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 22bdd1243dSDimitry Andric #include <optional> 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric namespace clang { 250b57cec5SDimitry Andric namespace targets { 260b57cec5SDimitry Andric 27349cc55cSDimitry Andric // Used by both the SPIR and SPIR-V targets. 28fe6060f1SDimitry Andric static const unsigned SPIRDefIsPrivMap[] = { 290b57cec5SDimitry Andric 0, // Default 300b57cec5SDimitry Andric 1, // opencl_global 310b57cec5SDimitry Andric 3, // opencl_local 320b57cec5SDimitry Andric 2, // opencl_constant 330b57cec5SDimitry Andric 0, // opencl_private 340b57cec5SDimitry Andric 4, // opencl_generic 35e8d8bef9SDimitry Andric 5, // opencl_global_device 36e8d8bef9SDimitry Andric 6, // opencl_global_host 370b57cec5SDimitry Andric 0, // cuda_device 380b57cec5SDimitry Andric 0, // cuda_constant 39480093f4SDimitry Andric 0, // cuda_shared 40fe6060f1SDimitry Andric // SYCL address space values for this map are dummy 41fe6060f1SDimitry Andric 0, // sycl_global 42fe6060f1SDimitry Andric 0, // sycl_global_device 43fe6060f1SDimitry Andric 0, // sycl_global_host 44fe6060f1SDimitry Andric 0, // sycl_local 45fe6060f1SDimitry Andric 0, // sycl_private 46fe6060f1SDimitry Andric 0, // ptr32_sptr 47fe6060f1SDimitry Andric 0, // ptr32_uptr 48bdd1243dSDimitry Andric 0, // ptr64 49bdd1243dSDimitry Andric 0, // hlsl_groupshared 5006c3fb27SDimitry Andric // Wasm address space values for this target are dummy values, 5106c3fb27SDimitry Andric // as it is only enabled for Wasm targets. 5206c3fb27SDimitry Andric 20, // wasm_funcref 53fe6060f1SDimitry Andric }; 54fe6060f1SDimitry Andric 55349cc55cSDimitry Andric // Used by both the SPIR and SPIR-V targets. 56fe6060f1SDimitry Andric static const unsigned SPIRDefIsGenMap[] = { 57fe6060f1SDimitry Andric 4, // Default 58fe6060f1SDimitry Andric // OpenCL address space values for this map are dummy and they can't be used 59fe6060f1SDimitry Andric 0, // opencl_global 60fe6060f1SDimitry Andric 0, // opencl_local 61fe6060f1SDimitry Andric 0, // opencl_constant 62fe6060f1SDimitry Andric 0, // opencl_private 63fe6060f1SDimitry Andric 0, // opencl_generic 64fe6060f1SDimitry Andric 0, // opencl_global_device 65fe6060f1SDimitry Andric 0, // opencl_global_host 664824e7fdSDimitry Andric // cuda_* address space mapping is intended for HIPSPV (HIP to SPIR-V 674824e7fdSDimitry Andric // translation). This mapping is enabled when the language mode is HIP. 684824e7fdSDimitry Andric 1, // cuda_device 694824e7fdSDimitry Andric // cuda_constant pointer can be casted to default/"flat" pointer, but in 704824e7fdSDimitry Andric // SPIR-V casts between constant and generic pointers are not allowed. For 714824e7fdSDimitry Andric // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup. 724824e7fdSDimitry Andric 1, // cuda_constant 734824e7fdSDimitry Andric 3, // cuda_shared 74fe6060f1SDimitry Andric 1, // sycl_global 75fe6060f1SDimitry Andric 5, // sycl_global_device 76fe6060f1SDimitry Andric 6, // sycl_global_host 77fe6060f1SDimitry Andric 3, // sycl_local 78fe6060f1SDimitry Andric 0, // sycl_private 79480093f4SDimitry Andric 0, // ptr32_sptr 80480093f4SDimitry Andric 0, // ptr32_uptr 81bdd1243dSDimitry Andric 0, // ptr64 82bdd1243dSDimitry Andric 0, // hlsl_groupshared 8306c3fb27SDimitry Andric // Wasm address space values for this target are dummy values, 8406c3fb27SDimitry Andric // as it is only enabled for Wasm targets. 8506c3fb27SDimitry Andric 20, // wasm_funcref 860b57cec5SDimitry Andric }; 870b57cec5SDimitry Andric 88349cc55cSDimitry Andric // Base class for SPIR and SPIR-V target info. 89349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { 9006c3fb27SDimitry Andric std::unique_ptr<TargetInfo> HostTarget; 9106c3fb27SDimitry Andric 92349cc55cSDimitry Andric protected: 9306c3fb27SDimitry Andric BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 940b57cec5SDimitry Andric : TargetInfo(Triple) { 954824e7fdSDimitry Andric assert((Triple.isSPIR() || Triple.isSPIRV()) && 964824e7fdSDimitry Andric "Invalid architecture for SPIR or SPIR-V."); 970b57cec5SDimitry Andric TLSSupported = false; 980b57cec5SDimitry Andric VLASupported = false; 990b57cec5SDimitry Andric LongWidth = LongAlign = 64; 100fe6060f1SDimitry Andric AddrSpaceMap = &SPIRDefIsPrivMap; 1010b57cec5SDimitry Andric UseAddrSpaceMapMangling = true; 1020b57cec5SDimitry Andric HasLegalHalfType = true; 1030b57cec5SDimitry Andric HasFloat16 = true; 1040b57cec5SDimitry Andric // Define available target features 1050b57cec5SDimitry Andric // These must be defined in sorted order! 1060b57cec5SDimitry Andric NoAsmVariants = true; 10706c3fb27SDimitry Andric 10806c3fb27SDimitry Andric llvm::Triple HostTriple(Opts.HostTriple); 10906c3fb27SDimitry Andric if (!HostTriple.isSPIR() && !HostTriple.isSPIRV() && 11006c3fb27SDimitry Andric HostTriple.getArch() != llvm::Triple::UnknownArch) { 11106c3fb27SDimitry Andric HostTarget = AllocateTarget(llvm::Triple(Opts.HostTriple), Opts); 11206c3fb27SDimitry Andric 11306c3fb27SDimitry Andric // Copy properties from host target. 11406c3fb27SDimitry Andric BoolWidth = HostTarget->getBoolWidth(); 11506c3fb27SDimitry Andric BoolAlign = HostTarget->getBoolAlign(); 11606c3fb27SDimitry Andric IntWidth = HostTarget->getIntWidth(); 11706c3fb27SDimitry Andric IntAlign = HostTarget->getIntAlign(); 11806c3fb27SDimitry Andric HalfWidth = HostTarget->getHalfWidth(); 11906c3fb27SDimitry Andric HalfAlign = HostTarget->getHalfAlign(); 12006c3fb27SDimitry Andric FloatWidth = HostTarget->getFloatWidth(); 12106c3fb27SDimitry Andric FloatAlign = HostTarget->getFloatAlign(); 12206c3fb27SDimitry Andric DoubleWidth = HostTarget->getDoubleWidth(); 12306c3fb27SDimitry Andric DoubleAlign = HostTarget->getDoubleAlign(); 12406c3fb27SDimitry Andric LongWidth = HostTarget->getLongWidth(); 12506c3fb27SDimitry Andric LongAlign = HostTarget->getLongAlign(); 12606c3fb27SDimitry Andric LongLongWidth = HostTarget->getLongLongWidth(); 12706c3fb27SDimitry Andric LongLongAlign = HostTarget->getLongLongAlign(); 128*0fca6ea1SDimitry Andric MinGlobalAlign = 129*0fca6ea1SDimitry Andric HostTarget->getMinGlobalAlign(/* TypeSize = */ 0, 130*0fca6ea1SDimitry Andric /* HasNonWeakDef = */ true); 13106c3fb27SDimitry Andric NewAlign = HostTarget->getNewAlign(); 13206c3fb27SDimitry Andric DefaultAlignForAttributeAligned = 13306c3fb27SDimitry Andric HostTarget->getDefaultAlignForAttributeAligned(); 13406c3fb27SDimitry Andric IntMaxType = HostTarget->getIntMaxType(); 13506c3fb27SDimitry Andric WCharType = HostTarget->getWCharType(); 13606c3fb27SDimitry Andric WIntType = HostTarget->getWIntType(); 13706c3fb27SDimitry Andric Char16Type = HostTarget->getChar16Type(); 13806c3fb27SDimitry Andric Char32Type = HostTarget->getChar32Type(); 13906c3fb27SDimitry Andric Int64Type = HostTarget->getInt64Type(); 14006c3fb27SDimitry Andric SigAtomicType = HostTarget->getSigAtomicType(); 14106c3fb27SDimitry Andric ProcessIDType = HostTarget->getProcessIDType(); 14206c3fb27SDimitry Andric 14306c3fb27SDimitry Andric UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment(); 14406c3fb27SDimitry Andric UseZeroLengthBitfieldAlignment = 14506c3fb27SDimitry Andric HostTarget->useZeroLengthBitfieldAlignment(); 14606c3fb27SDimitry Andric UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment(); 14706c3fb27SDimitry Andric ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary(); 14806c3fb27SDimitry Andric 14906c3fb27SDimitry Andric // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and 15006c3fb27SDimitry Andric // we need those macros to be identical on host and device, because (among 15106c3fb27SDimitry Andric // other things) they affect which standard library classes are defined, 15206c3fb27SDimitry Andric // and we need all classes to be defined on both the host and device. 15306c3fb27SDimitry Andric MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth(); 15406c3fb27SDimitry Andric } 1550b57cec5SDimitry Andric } 1560b57cec5SDimitry Andric 157349cc55cSDimitry Andric public: 1580b57cec5SDimitry Andric // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is 1590b57cec5SDimitry Andric // memcpy as per section 3 of the SPIR spec. 1600b57cec5SDimitry Andric bool useFP16ConversionIntrinsics() const override { return false; } 1610b57cec5SDimitry Andric 162bdd1243dSDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override { 163bdd1243dSDimitry Andric return std::nullopt; 164bdd1243dSDimitry Andric } 1650b57cec5SDimitry Andric 16606c3fb27SDimitry Andric std::string_view getClobbers() const override { return ""; } 1670b57cec5SDimitry Andric 168bdd1243dSDimitry Andric ArrayRef<const char *> getGCCRegNames() const override { 169bdd1243dSDimitry Andric return std::nullopt; 170bdd1243dSDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 1730b57cec5SDimitry Andric TargetInfo::ConstraintInfo &info) const override { 1740b57cec5SDimitry Andric return true; 1750b57cec5SDimitry Andric } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 178bdd1243dSDimitry Andric return std::nullopt; 1790b57cec5SDimitry Andric } 1800b57cec5SDimitry Andric 1810b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 1820b57cec5SDimitry Andric return TargetInfo::VoidPtrBuiltinVaList; 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric 185bdd1243dSDimitry Andric std::optional<unsigned> 186fe6060f1SDimitry Andric getDWARFAddressSpace(unsigned AddressSpace) const override { 187fe6060f1SDimitry Andric return AddressSpace; 188fe6060f1SDimitry Andric } 189fe6060f1SDimitry Andric 1900b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 1910b57cec5SDimitry Andric return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK 1920b57cec5SDimitry Andric : CCCR_Warning; 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric CallingConv getDefaultCallingConv() const override { 1960b57cec5SDimitry Andric return CC_SpirFunction; 1970b57cec5SDimitry Andric } 1980b57cec5SDimitry Andric 199fe6060f1SDimitry Andric void setAddressSpaceMap(bool DefaultIsGeneric) { 200fe6060f1SDimitry Andric AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap; 201fe6060f1SDimitry Andric } 202fe6060f1SDimitry Andric 203fe6060f1SDimitry Andric void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { 204fe6060f1SDimitry Andric TargetInfo::adjust(Diags, Opts); 205fe6060f1SDimitry Andric // FIXME: SYCL specification considers unannotated pointers and references 206fe6060f1SDimitry Andric // to be pointing to the generic address space. See section 5.9.3 of 207fe6060f1SDimitry Andric // SYCL 2020 specification. 20881ad6265SDimitry Andric // Currently, there is no way of representing SYCL's and HIP/CUDA's default 2094824e7fdSDimitry Andric // address space language semantic along with the semantics of embedded C's 2104824e7fdSDimitry Andric // default address space in the same address space map. Hence the map needs 2114824e7fdSDimitry Andric // to be reset to allow mapping to the desired value of 'Default' entry for 21281ad6265SDimitry Andric // SYCL and HIP/CUDA. 2134824e7fdSDimitry Andric setAddressSpaceMap( 2144824e7fdSDimitry Andric /*DefaultIsGeneric=*/Opts.SYCLIsDevice || 21581ad6265SDimitry Andric // The address mapping from HIP/CUDA language for device code is only 21681ad6265SDimitry Andric // defined for SPIR-V. 21781ad6265SDimitry Andric (getTriple().isSPIRV() && Opts.CUDAIsDevice)); 218fe6060f1SDimitry Andric } 219fe6060f1SDimitry Andric 2200b57cec5SDimitry Andric void setSupportedOpenCLOpts() override { 2210b57cec5SDimitry Andric // Assume all OpenCL extensions and optional core features are supported 222349cc55cSDimitry Andric // for SPIR and SPIR-V since they are generic targets. 223e8d8bef9SDimitry Andric supportAllOpenCLOpts(); 2240b57cec5SDimitry Andric } 2255ffd83dbSDimitry Andric 2260eae32dcSDimitry Andric bool hasBitIntType() const override { return true; } 227e8d8bef9SDimitry Andric 228e8d8bef9SDimitry Andric bool hasInt128Type() const override { return false; } 2290b57cec5SDimitry Andric }; 230fe6060f1SDimitry Andric 231349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo { 232349cc55cSDimitry Andric public: 233349cc55cSDimitry Andric SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 234349cc55cSDimitry Andric : BaseSPIRTargetInfo(Triple, Opts) { 2354824e7fdSDimitry Andric assert(Triple.isSPIR() && "Invalid architecture for SPIR."); 236349cc55cSDimitry Andric assert(getTriple().getOS() == llvm::Triple::UnknownOS && 237349cc55cSDimitry Andric "SPIR target must use unknown OS"); 238349cc55cSDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 239349cc55cSDimitry Andric "SPIR target must use unknown environment type"); 240349cc55cSDimitry Andric } 241349cc55cSDimitry Andric 242349cc55cSDimitry Andric void getTargetDefines(const LangOptions &Opts, 243349cc55cSDimitry Andric MacroBuilder &Builder) const override; 244349cc55cSDimitry Andric 245349cc55cSDimitry Andric bool hasFeature(StringRef Feature) const override { 246349cc55cSDimitry Andric return Feature == "spir"; 247349cc55cSDimitry Andric } 24806c3fb27SDimitry Andric 24906c3fb27SDimitry Andric bool checkArithmeticFenceSupported() const override { return true; } 250349cc55cSDimitry Andric }; 251349cc55cSDimitry Andric 2520b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { 2530b57cec5SDimitry Andric public: 2540b57cec5SDimitry Andric SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 2550b57cec5SDimitry Andric : SPIRTargetInfo(Triple, Opts) { 2564824e7fdSDimitry Andric assert(Triple.getArch() == llvm::Triple::spir && 2574824e7fdSDimitry Andric "Invalid architecture for 32-bit SPIR."); 2580b57cec5SDimitry Andric PointerWidth = PointerAlign = 32; 2590b57cec5SDimitry Andric SizeType = TargetInfo::UnsignedInt; 2600b57cec5SDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedInt; 2610b57cec5SDimitry Andric resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" 262*0fca6ea1SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"); 2630b57cec5SDimitry Andric } 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2660b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2670b57cec5SDimitry Andric }; 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { 2700b57cec5SDimitry Andric public: 2710b57cec5SDimitry Andric SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 2720b57cec5SDimitry Andric : SPIRTargetInfo(Triple, Opts) { 2734824e7fdSDimitry Andric assert(Triple.getArch() == llvm::Triple::spir64 && 2744824e7fdSDimitry Andric "Invalid architecture for 64-bit SPIR."); 2750b57cec5SDimitry Andric PointerWidth = PointerAlign = 64; 2760b57cec5SDimitry Andric SizeType = TargetInfo::UnsignedLong; 2770b57cec5SDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedLong; 2780b57cec5SDimitry Andric resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" 279*0fca6ea1SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"); 2800b57cec5SDimitry Andric } 2810b57cec5SDimitry Andric 2820b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2830b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2840b57cec5SDimitry Andric }; 285349cc55cSDimitry Andric 2865f757f3fSDimitry Andric class LLVM_LIBRARY_VISIBILITY BaseSPIRVTargetInfo : public BaseSPIRTargetInfo { 287349cc55cSDimitry Andric public: 2885f757f3fSDimitry Andric BaseSPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 289349cc55cSDimitry Andric : BaseSPIRTargetInfo(Triple, Opts) { 2904824e7fdSDimitry Andric assert(Triple.isSPIRV() && "Invalid architecture for SPIR-V."); 291349cc55cSDimitry Andric } 292349cc55cSDimitry Andric 293349cc55cSDimitry Andric bool hasFeature(StringRef Feature) const override { 294349cc55cSDimitry Andric return Feature == "spirv"; 295349cc55cSDimitry Andric } 2965f757f3fSDimitry Andric 2975f757f3fSDimitry Andric void getTargetDefines(const LangOptions &Opts, 2985f757f3fSDimitry Andric MacroBuilder &Builder) const override; 299349cc55cSDimitry Andric }; 300349cc55cSDimitry Andric 3015f757f3fSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRVTargetInfo { 3025f757f3fSDimitry Andric public: 3035f757f3fSDimitry Andric SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 3045f757f3fSDimitry Andric : BaseSPIRVTargetInfo(Triple, Opts) { 3055f757f3fSDimitry Andric assert(Triple.getArch() == llvm::Triple::spirv && 3065f757f3fSDimitry Andric "Invalid architecture for Logical SPIR-V."); 3077a6dacacSDimitry Andric assert(Triple.getOS() == llvm::Triple::Vulkan && 3087a6dacacSDimitry Andric Triple.getVulkanVersion() != llvm::VersionTuple(0) && 3097a6dacacSDimitry Andric "Logical SPIR-V requires a valid Vulkan environment."); 3105f757f3fSDimitry Andric assert(Triple.getEnvironment() >= llvm::Triple::Pixel && 3115f757f3fSDimitry Andric Triple.getEnvironment() <= llvm::Triple::Amplification && 3125f757f3fSDimitry Andric "Logical SPIR-V environment must be a valid shader stage."); 313*0fca6ea1SDimitry Andric PointerWidth = PointerAlign = 64; 3145f757f3fSDimitry Andric 3155f757f3fSDimitry Andric // SPIR-V IDs are represented with a single 32-bit word. 3165f757f3fSDimitry Andric SizeType = TargetInfo::UnsignedInt; 3175f757f3fSDimitry Andric resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" 318*0fca6ea1SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"); 3195f757f3fSDimitry Andric } 3205f757f3fSDimitry Andric 3215f757f3fSDimitry Andric void getTargetDefines(const LangOptions &Opts, 3225f757f3fSDimitry Andric MacroBuilder &Builder) const override; 3235f757f3fSDimitry Andric }; 3245f757f3fSDimitry Andric 3255f757f3fSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public BaseSPIRVTargetInfo { 326349cc55cSDimitry Andric public: 327349cc55cSDimitry Andric SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 3285f757f3fSDimitry Andric : BaseSPIRVTargetInfo(Triple, Opts) { 3294824e7fdSDimitry Andric assert(Triple.getArch() == llvm::Triple::spirv32 && 3304824e7fdSDimitry Andric "Invalid architecture for 32-bit SPIR-V."); 3315f757f3fSDimitry Andric assert(getTriple().getOS() == llvm::Triple::UnknownOS && 3325f757f3fSDimitry Andric "32-bit SPIR-V target must use unknown OS"); 3335f757f3fSDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 3345f757f3fSDimitry Andric "32-bit SPIR-V target must use unknown environment type"); 335349cc55cSDimitry Andric PointerWidth = PointerAlign = 32; 336349cc55cSDimitry Andric SizeType = TargetInfo::UnsignedInt; 337349cc55cSDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedInt; 338349cc55cSDimitry Andric resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" 339*0fca6ea1SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"); 340349cc55cSDimitry Andric } 341349cc55cSDimitry Andric 342349cc55cSDimitry Andric void getTargetDefines(const LangOptions &Opts, 343349cc55cSDimitry Andric MacroBuilder &Builder) const override; 344349cc55cSDimitry Andric }; 345349cc55cSDimitry Andric 3465f757f3fSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public BaseSPIRVTargetInfo { 347349cc55cSDimitry Andric public: 348349cc55cSDimitry Andric SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 3495f757f3fSDimitry Andric : BaseSPIRVTargetInfo(Triple, Opts) { 3504824e7fdSDimitry Andric assert(Triple.getArch() == llvm::Triple::spirv64 && 3514824e7fdSDimitry Andric "Invalid architecture for 64-bit SPIR-V."); 3525f757f3fSDimitry Andric assert(getTriple().getOS() == llvm::Triple::UnknownOS && 3535f757f3fSDimitry Andric "64-bit SPIR-V target must use unknown OS"); 3545f757f3fSDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 3555f757f3fSDimitry Andric "64-bit SPIR-V target must use unknown environment type"); 356349cc55cSDimitry Andric PointerWidth = PointerAlign = 64; 357349cc55cSDimitry Andric SizeType = TargetInfo::UnsignedLong; 358349cc55cSDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedLong; 359349cc55cSDimitry Andric resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" 360*0fca6ea1SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1"); 361349cc55cSDimitry Andric } 362349cc55cSDimitry Andric 363349cc55cSDimitry Andric void getTargetDefines(const LangOptions &Opts, 364349cc55cSDimitry Andric MacroBuilder &Builder) const override; 365349cc55cSDimitry Andric }; 366349cc55cSDimitry Andric 367*0fca6ea1SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRV64AMDGCNTargetInfo final 368*0fca6ea1SDimitry Andric : public BaseSPIRVTargetInfo { 369*0fca6ea1SDimitry Andric public: 370*0fca6ea1SDimitry Andric SPIRV64AMDGCNTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 371*0fca6ea1SDimitry Andric : BaseSPIRVTargetInfo(Triple, Opts) { 372*0fca6ea1SDimitry Andric assert(Triple.getArch() == llvm::Triple::spirv64 && 373*0fca6ea1SDimitry Andric "Invalid architecture for 64-bit AMDGCN SPIR-V."); 374*0fca6ea1SDimitry Andric assert(Triple.getVendor() == llvm::Triple::VendorType::AMD && 375*0fca6ea1SDimitry Andric "64-bit AMDGCN SPIR-V target must use AMD vendor"); 376*0fca6ea1SDimitry Andric assert(getTriple().getOS() == llvm::Triple::OSType::AMDHSA && 377*0fca6ea1SDimitry Andric "64-bit AMDGCN SPIR-V target must use AMDHSA OS"); 378*0fca6ea1SDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 379*0fca6ea1SDimitry Andric "64-bit SPIR-V target must use unknown environment type"); 380*0fca6ea1SDimitry Andric PointerWidth = PointerAlign = 64; 381*0fca6ea1SDimitry Andric SizeType = TargetInfo::UnsignedLong; 382*0fca6ea1SDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedLong; 383*0fca6ea1SDimitry Andric 384*0fca6ea1SDimitry Andric resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" 385*0fca6ea1SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024-G1-P4-A0"); 386*0fca6ea1SDimitry Andric 387*0fca6ea1SDimitry Andric BFloat16Width = BFloat16Align = 16; 388*0fca6ea1SDimitry Andric BFloat16Format = &llvm::APFloat::BFloat(); 389*0fca6ea1SDimitry Andric 390*0fca6ea1SDimitry Andric HasLegalHalfType = true; 391*0fca6ea1SDimitry Andric HasFloat16 = true; 392*0fca6ea1SDimitry Andric HalfArgsAndReturns = true; 393*0fca6ea1SDimitry Andric } 394*0fca6ea1SDimitry Andric 395*0fca6ea1SDimitry Andric bool hasBFloat16Type() const override { return true; } 396*0fca6ea1SDimitry Andric 397*0fca6ea1SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override; 398*0fca6ea1SDimitry Andric 399*0fca6ea1SDimitry Andric bool initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 400*0fca6ea1SDimitry Andric StringRef, 401*0fca6ea1SDimitry Andric const std::vector<std::string> &) const override; 402*0fca6ea1SDimitry Andric 403*0fca6ea1SDimitry Andric bool validateAsmConstraint(const char *&Name, 404*0fca6ea1SDimitry Andric TargetInfo::ConstraintInfo &Info) const override; 405*0fca6ea1SDimitry Andric 406*0fca6ea1SDimitry Andric std::string convertConstraint(const char *&Constraint) const override; 407*0fca6ea1SDimitry Andric 408*0fca6ea1SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 409*0fca6ea1SDimitry Andric 410*0fca6ea1SDimitry Andric void getTargetDefines(const LangOptions &Opts, 411*0fca6ea1SDimitry Andric MacroBuilder &Builder) const override; 412*0fca6ea1SDimitry Andric 413*0fca6ea1SDimitry Andric void setAuxTarget(const TargetInfo *Aux) override; 414*0fca6ea1SDimitry Andric 415*0fca6ea1SDimitry Andric bool hasInt128Type() const override { return TargetInfo::hasInt128Type(); } 416*0fca6ea1SDimitry Andric }; 417*0fca6ea1SDimitry Andric 4180b57cec5SDimitry Andric } // namespace targets 4190b57cec5SDimitry Andric } // namespace clang 4200b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H 421