1*349cc55cSDimitry 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 // 9*349cc55cSDimitry 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 160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 180b57cec5SDimitry Andric #include "llvm/ADT/Triple.h" 190b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace clang { 220b57cec5SDimitry Andric namespace targets { 230b57cec5SDimitry Andric 24*349cc55cSDimitry Andric // Used by both the SPIR and SPIR-V targets. 25fe6060f1SDimitry Andric static const unsigned SPIRDefIsPrivMap[] = { 260b57cec5SDimitry Andric 0, // Default 270b57cec5SDimitry Andric 1, // opencl_global 280b57cec5SDimitry Andric 3, // opencl_local 290b57cec5SDimitry Andric 2, // opencl_constant 300b57cec5SDimitry Andric 0, // opencl_private 310b57cec5SDimitry Andric 4, // opencl_generic 32e8d8bef9SDimitry Andric 5, // opencl_global_device 33e8d8bef9SDimitry Andric 6, // opencl_global_host 340b57cec5SDimitry Andric 0, // cuda_device 350b57cec5SDimitry Andric 0, // cuda_constant 36480093f4SDimitry Andric 0, // cuda_shared 37fe6060f1SDimitry Andric // SYCL address space values for this map are dummy 38fe6060f1SDimitry Andric 0, // sycl_global 39fe6060f1SDimitry Andric 0, // sycl_global_device 40fe6060f1SDimitry Andric 0, // sycl_global_host 41fe6060f1SDimitry Andric 0, // sycl_local 42fe6060f1SDimitry Andric 0, // sycl_private 43fe6060f1SDimitry Andric 0, // ptr32_sptr 44fe6060f1SDimitry Andric 0, // ptr32_uptr 45fe6060f1SDimitry Andric 0 // ptr64 46fe6060f1SDimitry Andric }; 47fe6060f1SDimitry Andric 48*349cc55cSDimitry Andric // Used by both the SPIR and SPIR-V targets. 49fe6060f1SDimitry Andric static const unsigned SPIRDefIsGenMap[] = { 50fe6060f1SDimitry Andric 4, // Default 51fe6060f1SDimitry Andric // OpenCL address space values for this map are dummy and they can't be used 52fe6060f1SDimitry Andric 0, // opencl_global 53fe6060f1SDimitry Andric 0, // opencl_local 54fe6060f1SDimitry Andric 0, // opencl_constant 55fe6060f1SDimitry Andric 0, // opencl_private 56fe6060f1SDimitry Andric 0, // opencl_generic 57fe6060f1SDimitry Andric 0, // opencl_global_device 58fe6060f1SDimitry Andric 0, // opencl_global_host 59fe6060f1SDimitry Andric 0, // cuda_device 60fe6060f1SDimitry Andric 0, // cuda_constant 61fe6060f1SDimitry Andric 0, // cuda_shared 62fe6060f1SDimitry Andric 1, // sycl_global 63fe6060f1SDimitry Andric 5, // sycl_global_device 64fe6060f1SDimitry Andric 6, // sycl_global_host 65fe6060f1SDimitry Andric 3, // sycl_local 66fe6060f1SDimitry Andric 0, // sycl_private 67480093f4SDimitry Andric 0, // ptr32_sptr 68480093f4SDimitry Andric 0, // ptr32_uptr 69480093f4SDimitry Andric 0 // ptr64 700b57cec5SDimitry Andric }; 710b57cec5SDimitry Andric 72*349cc55cSDimitry Andric // Base class for SPIR and SPIR-V target info. 73*349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo { 74*349cc55cSDimitry Andric protected: 75*349cc55cSDimitry Andric BaseSPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 760b57cec5SDimitry Andric : TargetInfo(Triple) { 770b57cec5SDimitry Andric assert(getTriple().getOS() == llvm::Triple::UnknownOS && 78*349cc55cSDimitry Andric "SPIR(-V) target must use unknown OS"); 790b57cec5SDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 80*349cc55cSDimitry Andric "SPIR(-V) target must use unknown environment type"); 810b57cec5SDimitry Andric TLSSupported = false; 820b57cec5SDimitry Andric VLASupported = false; 830b57cec5SDimitry Andric LongWidth = LongAlign = 64; 84fe6060f1SDimitry Andric AddrSpaceMap = &SPIRDefIsPrivMap; 850b57cec5SDimitry Andric UseAddrSpaceMapMangling = true; 860b57cec5SDimitry Andric HasLegalHalfType = true; 870b57cec5SDimitry Andric HasFloat16 = true; 880b57cec5SDimitry Andric // Define available target features 890b57cec5SDimitry Andric // These must be defined in sorted order! 900b57cec5SDimitry Andric NoAsmVariants = true; 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 93*349cc55cSDimitry Andric public: 940b57cec5SDimitry Andric // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is 950b57cec5SDimitry Andric // memcpy as per section 3 of the SPIR spec. 960b57cec5SDimitry Andric bool useFP16ConversionIntrinsics() const override { return false; } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric const char *getClobbers() const override { return ""; } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override { return None; } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 1050b57cec5SDimitry Andric TargetInfo::ConstraintInfo &info) const override { 1060b57cec5SDimitry Andric return true; 1070b57cec5SDimitry Andric } 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 1100b57cec5SDimitry Andric return None; 1110b57cec5SDimitry Andric } 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 1140b57cec5SDimitry Andric return TargetInfo::VoidPtrBuiltinVaList; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 117fe6060f1SDimitry Andric Optional<unsigned> 118fe6060f1SDimitry Andric getDWARFAddressSpace(unsigned AddressSpace) const override { 119fe6060f1SDimitry Andric return AddressSpace; 120fe6060f1SDimitry Andric } 121fe6060f1SDimitry Andric 1220b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 1230b57cec5SDimitry Andric return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK 1240b57cec5SDimitry Andric : CCCR_Warning; 1250b57cec5SDimitry Andric } 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric CallingConv getDefaultCallingConv() const override { 1280b57cec5SDimitry Andric return CC_SpirFunction; 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric 131fe6060f1SDimitry Andric void setAddressSpaceMap(bool DefaultIsGeneric) { 132fe6060f1SDimitry Andric AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap; 133fe6060f1SDimitry Andric } 134fe6060f1SDimitry Andric 135fe6060f1SDimitry Andric void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { 136fe6060f1SDimitry Andric TargetInfo::adjust(Diags, Opts); 137fe6060f1SDimitry Andric // FIXME: SYCL specification considers unannotated pointers and references 138fe6060f1SDimitry Andric // to be pointing to the generic address space. See section 5.9.3 of 139fe6060f1SDimitry Andric // SYCL 2020 specification. 140fe6060f1SDimitry Andric // Currently, there is no way of representing SYCL's default address space 141fe6060f1SDimitry Andric // language semantic along with the semantics of embedded C's default 142fe6060f1SDimitry Andric // address space in the same address space map. Hence the map needs to be 143fe6060f1SDimitry Andric // reset to allow mapping to the desired value of 'Default' entry for SYCL. 144fe6060f1SDimitry Andric setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice); 145fe6060f1SDimitry Andric } 146fe6060f1SDimitry Andric 1470b57cec5SDimitry Andric void setSupportedOpenCLOpts() override { 1480b57cec5SDimitry Andric // Assume all OpenCL extensions and optional core features are supported 149*349cc55cSDimitry Andric // for SPIR and SPIR-V since they are generic targets. 150e8d8bef9SDimitry Andric supportAllOpenCLOpts(); 1510b57cec5SDimitry Andric } 1525ffd83dbSDimitry Andric 1535ffd83dbSDimitry Andric bool hasExtIntType() const override { return true; } 154e8d8bef9SDimitry Andric 155e8d8bef9SDimitry Andric bool hasInt128Type() const override { return false; } 1560b57cec5SDimitry Andric }; 157fe6060f1SDimitry Andric 158*349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public BaseSPIRTargetInfo { 159*349cc55cSDimitry Andric public: 160*349cc55cSDimitry Andric SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 161*349cc55cSDimitry Andric : BaseSPIRTargetInfo(Triple, Opts) { 162*349cc55cSDimitry Andric assert(getTriple().getOS() == llvm::Triple::UnknownOS && 163*349cc55cSDimitry Andric "SPIR target must use unknown OS"); 164*349cc55cSDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 165*349cc55cSDimitry Andric "SPIR target must use unknown environment type"); 166*349cc55cSDimitry Andric } 167*349cc55cSDimitry Andric 168*349cc55cSDimitry Andric void getTargetDefines(const LangOptions &Opts, 169*349cc55cSDimitry Andric MacroBuilder &Builder) const override; 170*349cc55cSDimitry Andric 171*349cc55cSDimitry Andric bool hasFeature(StringRef Feature) const override { 172*349cc55cSDimitry Andric return Feature == "spir"; 173*349cc55cSDimitry Andric } 174*349cc55cSDimitry Andric }; 175*349cc55cSDimitry Andric 1760b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { 1770b57cec5SDimitry Andric public: 1780b57cec5SDimitry Andric SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 1790b57cec5SDimitry Andric : SPIRTargetInfo(Triple, Opts) { 1800b57cec5SDimitry Andric PointerWidth = PointerAlign = 32; 1810b57cec5SDimitry Andric SizeType = TargetInfo::UnsignedInt; 1820b57cec5SDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedInt; 1830b57cec5SDimitry Andric resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" 1840b57cec5SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024"); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 1880b57cec5SDimitry Andric MacroBuilder &Builder) const override; 1890b57cec5SDimitry Andric }; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { 1920b57cec5SDimitry Andric public: 1930b57cec5SDimitry Andric SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 1940b57cec5SDimitry Andric : SPIRTargetInfo(Triple, Opts) { 1950b57cec5SDimitry Andric PointerWidth = PointerAlign = 64; 1960b57cec5SDimitry Andric SizeType = TargetInfo::UnsignedLong; 1970b57cec5SDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedLong; 1980b57cec5SDimitry Andric resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" 1990b57cec5SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024"); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 2030b57cec5SDimitry Andric MacroBuilder &Builder) const override; 2040b57cec5SDimitry Andric }; 205*349cc55cSDimitry Andric 206*349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRVTargetInfo : public BaseSPIRTargetInfo { 207*349cc55cSDimitry Andric public: 208*349cc55cSDimitry Andric SPIRVTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 209*349cc55cSDimitry Andric : BaseSPIRTargetInfo(Triple, Opts) { 210*349cc55cSDimitry Andric assert(getTriple().getOS() == llvm::Triple::UnknownOS && 211*349cc55cSDimitry Andric "SPIR-V target must use unknown OS"); 212*349cc55cSDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 213*349cc55cSDimitry Andric "SPIR-V target must use unknown environment type"); 214*349cc55cSDimitry Andric } 215*349cc55cSDimitry Andric 216*349cc55cSDimitry Andric void getTargetDefines(const LangOptions &Opts, 217*349cc55cSDimitry Andric MacroBuilder &Builder) const override; 218*349cc55cSDimitry Andric 219*349cc55cSDimitry Andric bool hasFeature(StringRef Feature) const override { 220*349cc55cSDimitry Andric return Feature == "spirv"; 221*349cc55cSDimitry Andric } 222*349cc55cSDimitry Andric }; 223*349cc55cSDimitry Andric 224*349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRV32TargetInfo : public SPIRVTargetInfo { 225*349cc55cSDimitry Andric public: 226*349cc55cSDimitry Andric SPIRV32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 227*349cc55cSDimitry Andric : SPIRVTargetInfo(Triple, Opts) { 228*349cc55cSDimitry Andric PointerWidth = PointerAlign = 32; 229*349cc55cSDimitry Andric SizeType = TargetInfo::UnsignedInt; 230*349cc55cSDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedInt; 231*349cc55cSDimitry Andric resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" 232*349cc55cSDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024"); 233*349cc55cSDimitry Andric } 234*349cc55cSDimitry Andric 235*349cc55cSDimitry Andric void getTargetDefines(const LangOptions &Opts, 236*349cc55cSDimitry Andric MacroBuilder &Builder) const override; 237*349cc55cSDimitry Andric }; 238*349cc55cSDimitry Andric 239*349cc55cSDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRV64TargetInfo : public SPIRVTargetInfo { 240*349cc55cSDimitry Andric public: 241*349cc55cSDimitry Andric SPIRV64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 242*349cc55cSDimitry Andric : SPIRVTargetInfo(Triple, Opts) { 243*349cc55cSDimitry Andric PointerWidth = PointerAlign = 64; 244*349cc55cSDimitry Andric SizeType = TargetInfo::UnsignedLong; 245*349cc55cSDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedLong; 246*349cc55cSDimitry Andric resetDataLayout("e-i64:64-v16:16-v24:32-v32:32-v48:64-" 247*349cc55cSDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024"); 248*349cc55cSDimitry Andric } 249*349cc55cSDimitry Andric 250*349cc55cSDimitry Andric void getTargetDefines(const LangOptions &Opts, 251*349cc55cSDimitry Andric MacroBuilder &Builder) const override; 252*349cc55cSDimitry Andric }; 253*349cc55cSDimitry Andric 2540b57cec5SDimitry Andric } // namespace targets 2550b57cec5SDimitry Andric } // namespace clang 2560b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H 257