xref: /freebsd-src/contrib/llvm-project/clang/lib/Basic/Targets/SPIR.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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