10b57cec5SDimitry Andric //===--- SPIR.h - Declare SPIR 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 // 90b57cec5SDimitry Andric // This file declares SPIR 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*fe6060f1SDimitry Andric static const unsigned SPIRDefIsPrivMap[] = { 250b57cec5SDimitry Andric 0, // Default 260b57cec5SDimitry Andric 1, // opencl_global 270b57cec5SDimitry Andric 3, // opencl_local 280b57cec5SDimitry Andric 2, // opencl_constant 290b57cec5SDimitry Andric 0, // opencl_private 300b57cec5SDimitry Andric 4, // opencl_generic 31e8d8bef9SDimitry Andric 5, // opencl_global_device 32e8d8bef9SDimitry Andric 6, // opencl_global_host 330b57cec5SDimitry Andric 0, // cuda_device 340b57cec5SDimitry Andric 0, // cuda_constant 35480093f4SDimitry Andric 0, // cuda_shared 36*fe6060f1SDimitry Andric // SYCL address space values for this map are dummy 37*fe6060f1SDimitry Andric 0, // sycl_global 38*fe6060f1SDimitry Andric 0, // sycl_global_device 39*fe6060f1SDimitry Andric 0, // sycl_global_host 40*fe6060f1SDimitry Andric 0, // sycl_local 41*fe6060f1SDimitry Andric 0, // sycl_private 42*fe6060f1SDimitry Andric 0, // ptr32_sptr 43*fe6060f1SDimitry Andric 0, // ptr32_uptr 44*fe6060f1SDimitry Andric 0 // ptr64 45*fe6060f1SDimitry Andric }; 46*fe6060f1SDimitry Andric 47*fe6060f1SDimitry Andric static const unsigned SPIRDefIsGenMap[] = { 48*fe6060f1SDimitry Andric 4, // Default 49*fe6060f1SDimitry Andric // OpenCL address space values for this map are dummy and they can't be used 50*fe6060f1SDimitry Andric 0, // opencl_global 51*fe6060f1SDimitry Andric 0, // opencl_local 52*fe6060f1SDimitry Andric 0, // opencl_constant 53*fe6060f1SDimitry Andric 0, // opencl_private 54*fe6060f1SDimitry Andric 0, // opencl_generic 55*fe6060f1SDimitry Andric 0, // opencl_global_device 56*fe6060f1SDimitry Andric 0, // opencl_global_host 57*fe6060f1SDimitry Andric 0, // cuda_device 58*fe6060f1SDimitry Andric 0, // cuda_constant 59*fe6060f1SDimitry Andric 0, // cuda_shared 60*fe6060f1SDimitry Andric 1, // sycl_global 61*fe6060f1SDimitry Andric 5, // sycl_global_device 62*fe6060f1SDimitry Andric 6, // sycl_global_host 63*fe6060f1SDimitry Andric 3, // sycl_local 64*fe6060f1SDimitry Andric 0, // sycl_private 65480093f4SDimitry Andric 0, // ptr32_sptr 66480093f4SDimitry Andric 0, // ptr32_uptr 67480093f4SDimitry Andric 0 // ptr64 680b57cec5SDimitry Andric }; 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo { 710b57cec5SDimitry Andric public: 720b57cec5SDimitry Andric SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 730b57cec5SDimitry Andric : TargetInfo(Triple) { 740b57cec5SDimitry Andric assert(getTriple().getOS() == llvm::Triple::UnknownOS && 750b57cec5SDimitry Andric "SPIR target must use unknown OS"); 760b57cec5SDimitry Andric assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment && 770b57cec5SDimitry Andric "SPIR target must use unknown environment type"); 780b57cec5SDimitry Andric TLSSupported = false; 790b57cec5SDimitry Andric VLASupported = false; 800b57cec5SDimitry Andric LongWidth = LongAlign = 64; 81*fe6060f1SDimitry Andric AddrSpaceMap = &SPIRDefIsPrivMap; 820b57cec5SDimitry Andric UseAddrSpaceMapMangling = true; 830b57cec5SDimitry Andric HasLegalHalfType = true; 840b57cec5SDimitry Andric HasFloat16 = true; 850b57cec5SDimitry Andric // Define available target features 860b57cec5SDimitry Andric // These must be defined in sorted order! 870b57cec5SDimitry Andric NoAsmVariants = true; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric 900b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 910b57cec5SDimitry Andric MacroBuilder &Builder) const override; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override { 940b57cec5SDimitry Andric return Feature == "spir"; 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is 980b57cec5SDimitry Andric // memcpy as per section 3 of the SPIR spec. 990b57cec5SDimitry Andric bool useFP16ConversionIntrinsics() const override { return false; } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override { return None; } 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric const char *getClobbers() const override { return ""; } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override { return None; } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 1080b57cec5SDimitry Andric TargetInfo::ConstraintInfo &info) const override { 1090b57cec5SDimitry Andric return true; 1100b57cec5SDimitry Andric } 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 1130b57cec5SDimitry Andric return None; 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 1170b57cec5SDimitry Andric return TargetInfo::VoidPtrBuiltinVaList; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 120*fe6060f1SDimitry Andric Optional<unsigned> 121*fe6060f1SDimitry Andric getDWARFAddressSpace(unsigned AddressSpace) const override { 122*fe6060f1SDimitry Andric return AddressSpace; 123*fe6060f1SDimitry Andric } 124*fe6060f1SDimitry Andric 1250b57cec5SDimitry Andric CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { 1260b57cec5SDimitry Andric return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK 1270b57cec5SDimitry Andric : CCCR_Warning; 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric CallingConv getDefaultCallingConv() const override { 1310b57cec5SDimitry Andric return CC_SpirFunction; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 134*fe6060f1SDimitry Andric void setAddressSpaceMap(bool DefaultIsGeneric) { 135*fe6060f1SDimitry Andric AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap; 136*fe6060f1SDimitry Andric } 137*fe6060f1SDimitry Andric 138*fe6060f1SDimitry Andric void adjust(DiagnosticsEngine &Diags, LangOptions &Opts) override { 139*fe6060f1SDimitry Andric TargetInfo::adjust(Diags, Opts); 140*fe6060f1SDimitry Andric // FIXME: SYCL specification considers unannotated pointers and references 141*fe6060f1SDimitry Andric // to be pointing to the generic address space. See section 5.9.3 of 142*fe6060f1SDimitry Andric // SYCL 2020 specification. 143*fe6060f1SDimitry Andric // Currently, there is no way of representing SYCL's default address space 144*fe6060f1SDimitry Andric // language semantic along with the semantics of embedded C's default 145*fe6060f1SDimitry Andric // address space in the same address space map. Hence the map needs to be 146*fe6060f1SDimitry Andric // reset to allow mapping to the desired value of 'Default' entry for SYCL. 147*fe6060f1SDimitry Andric setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice); 148*fe6060f1SDimitry Andric } 149*fe6060f1SDimitry Andric 1500b57cec5SDimitry Andric void setSupportedOpenCLOpts() override { 1510b57cec5SDimitry Andric // Assume all OpenCL extensions and optional core features are supported 1520b57cec5SDimitry Andric // for SPIR since it is a generic target. 153e8d8bef9SDimitry Andric supportAllOpenCLOpts(); 1540b57cec5SDimitry Andric } 1555ffd83dbSDimitry Andric 1565ffd83dbSDimitry Andric bool hasExtIntType() const override { return true; } 157e8d8bef9SDimitry Andric 158e8d8bef9SDimitry Andric bool hasInt128Type() const override { return false; } 1590b57cec5SDimitry Andric }; 160*fe6060f1SDimitry Andric 1610b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo { 1620b57cec5SDimitry Andric public: 1630b57cec5SDimitry Andric SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 1640b57cec5SDimitry Andric : SPIRTargetInfo(Triple, Opts) { 1650b57cec5SDimitry Andric PointerWidth = PointerAlign = 32; 1660b57cec5SDimitry Andric SizeType = TargetInfo::UnsignedInt; 1670b57cec5SDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedInt; 1680b57cec5SDimitry Andric resetDataLayout("e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-" 1690b57cec5SDimitry Andric "v96:128-v192:256-v256:256-v512:512-v1024:1024"); 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 1730b57cec5SDimitry Andric MacroBuilder &Builder) const override; 1740b57cec5SDimitry Andric }; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo { 1770b57cec5SDimitry Andric public: 1780b57cec5SDimitry Andric SPIR64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 1790b57cec5SDimitry Andric : SPIRTargetInfo(Triple, Opts) { 1800b57cec5SDimitry Andric PointerWidth = PointerAlign = 64; 1810b57cec5SDimitry Andric SizeType = TargetInfo::UnsignedLong; 1820b57cec5SDimitry Andric PtrDiffType = IntPtrType = TargetInfo::SignedLong; 1830b57cec5SDimitry Andric resetDataLayout("e-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 } // namespace targets 1910b57cec5SDimitry Andric } // namespace clang 1920b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H 193