xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/NVPTX.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- NVPTX.cpp - Implement NVPTX target feature support ---------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements NVPTX TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "NVPTX.h"
14e5dd7070Spatrick #include "Targets.h"
15e5dd7070Spatrick #include "clang/Basic/Builtins.h"
16e5dd7070Spatrick #include "clang/Basic/MacroBuilder.h"
17e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h"
18e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
19e5dd7070Spatrick 
20e5dd7070Spatrick using namespace clang;
21e5dd7070Spatrick using namespace clang::targets;
22e5dd7070Spatrick 
23*12c85518Srobert static constexpr Builtin::Info BuiltinInfo[] = {
24e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
25*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
26e5dd7070Spatrick #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
27*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
28e5dd7070Spatrick #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
29*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
30e5dd7070Spatrick #include "clang/Basic/BuiltinsNVPTX.def"
31e5dd7070Spatrick };
32e5dd7070Spatrick 
33e5dd7070Spatrick const char *const NVPTXTargetInfo::GCCRegNames[] = {"r0"};
34e5dd7070Spatrick 
NVPTXTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts,unsigned TargetPointerWidth)35e5dd7070Spatrick NVPTXTargetInfo::NVPTXTargetInfo(const llvm::Triple &Triple,
36e5dd7070Spatrick                                  const TargetOptions &Opts,
37e5dd7070Spatrick                                  unsigned TargetPointerWidth)
38e5dd7070Spatrick     : TargetInfo(Triple) {
39e5dd7070Spatrick   assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) &&
40e5dd7070Spatrick          "NVPTX only supports 32- and 64-bit modes.");
41e5dd7070Spatrick 
42e5dd7070Spatrick   PTXVersion = 32;
43e5dd7070Spatrick   for (const StringRef Feature : Opts.FeaturesAsWritten) {
44*12c85518Srobert     int PTXV;
45*12c85518Srobert     if (!Feature.startswith("+ptx") ||
46*12c85518Srobert         Feature.drop_front(4).getAsInteger(10, PTXV))
47e5dd7070Spatrick       continue;
48*12c85518Srobert     PTXVersion = PTXV; // TODO: should it be max(PTXVersion, PTXV)?
49e5dd7070Spatrick   }
50e5dd7070Spatrick 
51e5dd7070Spatrick   TLSSupported = false;
52e5dd7070Spatrick   VLASupported = false;
53e5dd7070Spatrick   AddrSpaceMap = &NVPTXAddrSpaceMap;
54e5dd7070Spatrick   UseAddrSpaceMapMangling = true;
55*12c85518Srobert   // __bf16 is always available as a load/store only type.
56*12c85518Srobert   BFloat16Width = BFloat16Align = 16;
57*12c85518Srobert   BFloat16Format = &llvm::APFloat::BFloat();
58e5dd7070Spatrick 
59e5dd7070Spatrick   // Define available target features
60e5dd7070Spatrick   // These must be defined in sorted order!
61e5dd7070Spatrick   NoAsmVariants = true;
62e5dd7070Spatrick   GPU = CudaArch::SM_20;
63e5dd7070Spatrick 
64e5dd7070Spatrick   if (TargetPointerWidth == 32)
65e5dd7070Spatrick     resetDataLayout("e-p:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
66e5dd7070Spatrick   else if (Opts.NVPTXUseShortPointers)
67e5dd7070Spatrick     resetDataLayout(
68e5dd7070Spatrick         "e-p3:32:32-p4:32:32-p5:32:32-i64:64-i128:128-v16:16-v32:32-n16:32:64");
69e5dd7070Spatrick   else
70e5dd7070Spatrick     resetDataLayout("e-i64:64-i128:128-v16:16-v32:32-n16:32:64");
71e5dd7070Spatrick 
72e5dd7070Spatrick   // If possible, get a TargetInfo for our host triple, so we can match its
73e5dd7070Spatrick   // types.
74e5dd7070Spatrick   llvm::Triple HostTriple(Opts.HostTriple);
75e5dd7070Spatrick   if (!HostTriple.isNVPTX())
76e5dd7070Spatrick     HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts));
77e5dd7070Spatrick 
78e5dd7070Spatrick   // If no host target, make some guesses about the data layout and return.
79e5dd7070Spatrick   if (!HostTarget) {
80e5dd7070Spatrick     LongWidth = LongAlign = TargetPointerWidth;
81e5dd7070Spatrick     PointerWidth = PointerAlign = TargetPointerWidth;
82e5dd7070Spatrick     switch (TargetPointerWidth) {
83e5dd7070Spatrick     case 32:
84e5dd7070Spatrick       SizeType = TargetInfo::UnsignedInt;
85e5dd7070Spatrick       PtrDiffType = TargetInfo::SignedInt;
86e5dd7070Spatrick       IntPtrType = TargetInfo::SignedInt;
87e5dd7070Spatrick       break;
88e5dd7070Spatrick     case 64:
89e5dd7070Spatrick       SizeType = TargetInfo::UnsignedLong;
90e5dd7070Spatrick       PtrDiffType = TargetInfo::SignedLong;
91e5dd7070Spatrick       IntPtrType = TargetInfo::SignedLong;
92e5dd7070Spatrick       break;
93e5dd7070Spatrick     default:
94e5dd7070Spatrick       llvm_unreachable("TargetPointerWidth must be 32 or 64");
95e5dd7070Spatrick     }
96e5dd7070Spatrick     return;
97e5dd7070Spatrick   }
98e5dd7070Spatrick 
99e5dd7070Spatrick   // Copy properties from host target.
100*12c85518Srobert   PointerWidth = HostTarget->getPointerWidth(LangAS::Default);
101*12c85518Srobert   PointerAlign = HostTarget->getPointerAlign(LangAS::Default);
102e5dd7070Spatrick   BoolWidth = HostTarget->getBoolWidth();
103e5dd7070Spatrick   BoolAlign = HostTarget->getBoolAlign();
104e5dd7070Spatrick   IntWidth = HostTarget->getIntWidth();
105e5dd7070Spatrick   IntAlign = HostTarget->getIntAlign();
106e5dd7070Spatrick   HalfWidth = HostTarget->getHalfWidth();
107e5dd7070Spatrick   HalfAlign = HostTarget->getHalfAlign();
108e5dd7070Spatrick   FloatWidth = HostTarget->getFloatWidth();
109e5dd7070Spatrick   FloatAlign = HostTarget->getFloatAlign();
110e5dd7070Spatrick   DoubleWidth = HostTarget->getDoubleWidth();
111e5dd7070Spatrick   DoubleAlign = HostTarget->getDoubleAlign();
112e5dd7070Spatrick   LongWidth = HostTarget->getLongWidth();
113e5dd7070Spatrick   LongAlign = HostTarget->getLongAlign();
114e5dd7070Spatrick   LongLongWidth = HostTarget->getLongLongWidth();
115e5dd7070Spatrick   LongLongAlign = HostTarget->getLongLongAlign();
116e5dd7070Spatrick   MinGlobalAlign = HostTarget->getMinGlobalAlign(/* TypeSize = */ 0);
117e5dd7070Spatrick   NewAlign = HostTarget->getNewAlign();
118e5dd7070Spatrick   DefaultAlignForAttributeAligned =
119e5dd7070Spatrick       HostTarget->getDefaultAlignForAttributeAligned();
120e5dd7070Spatrick   SizeType = HostTarget->getSizeType();
121e5dd7070Spatrick   IntMaxType = HostTarget->getIntMaxType();
122*12c85518Srobert   PtrDiffType = HostTarget->getPtrDiffType(LangAS::Default);
123e5dd7070Spatrick   IntPtrType = HostTarget->getIntPtrType();
124e5dd7070Spatrick   WCharType = HostTarget->getWCharType();
125e5dd7070Spatrick   WIntType = HostTarget->getWIntType();
126e5dd7070Spatrick   Char16Type = HostTarget->getChar16Type();
127e5dd7070Spatrick   Char32Type = HostTarget->getChar32Type();
128e5dd7070Spatrick   Int64Type = HostTarget->getInt64Type();
129e5dd7070Spatrick   SigAtomicType = HostTarget->getSigAtomicType();
130e5dd7070Spatrick   ProcessIDType = HostTarget->getProcessIDType();
131e5dd7070Spatrick 
132e5dd7070Spatrick   UseBitFieldTypeAlignment = HostTarget->useBitFieldTypeAlignment();
133e5dd7070Spatrick   UseZeroLengthBitfieldAlignment = HostTarget->useZeroLengthBitfieldAlignment();
134e5dd7070Spatrick   UseExplicitBitFieldAlignment = HostTarget->useExplicitBitFieldAlignment();
135e5dd7070Spatrick   ZeroLengthBitfieldBoundary = HostTarget->getZeroLengthBitfieldBoundary();
136e5dd7070Spatrick 
137e5dd7070Spatrick   // This is a bit of a lie, but it controls __GCC_ATOMIC_XXX_LOCK_FREE, and
138e5dd7070Spatrick   // we need those macros to be identical on host and device, because (among
139e5dd7070Spatrick   // other things) they affect which standard library classes are defined, and
140e5dd7070Spatrick   // we need all classes to be defined on both the host and device.
141e5dd7070Spatrick   MaxAtomicInlineWidth = HostTarget->getMaxAtomicInlineWidth();
142e5dd7070Spatrick 
143e5dd7070Spatrick   // Properties intentionally not copied from host:
144e5dd7070Spatrick   // - LargeArrayMinWidth, LargeArrayAlign: Not visible across the
145e5dd7070Spatrick   //   host/device boundary.
146e5dd7070Spatrick   // - SuitableAlign: Not visible across the host/device boundary, and may
147e5dd7070Spatrick   //   correctly be different on host/device, e.g. if host has wider vector
148e5dd7070Spatrick   //   types than device.
149e5dd7070Spatrick   // - LongDoubleWidth, LongDoubleAlign: nvptx's long double type is the same
150e5dd7070Spatrick   //   as its double type, but that's not necessarily true on the host.
151e5dd7070Spatrick   //   TODO: nvcc emits a warning when using long double on device; we should
152e5dd7070Spatrick   //   do the same.
153e5dd7070Spatrick }
154e5dd7070Spatrick 
getGCCRegNames() const155e5dd7070Spatrick ArrayRef<const char *> NVPTXTargetInfo::getGCCRegNames() const {
156*12c85518Srobert   return llvm::ArrayRef(GCCRegNames);
157e5dd7070Spatrick }
158e5dd7070Spatrick 
hasFeature(StringRef Feature) const159e5dd7070Spatrick bool NVPTXTargetInfo::hasFeature(StringRef Feature) const {
160e5dd7070Spatrick   return llvm::StringSwitch<bool>(Feature)
161e5dd7070Spatrick       .Cases("ptx", "nvptx", true)
162e5dd7070Spatrick       .Default(false);
163e5dd7070Spatrick }
164e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const165e5dd7070Spatrick void NVPTXTargetInfo::getTargetDefines(const LangOptions &Opts,
166e5dd7070Spatrick                                        MacroBuilder &Builder) const {
167e5dd7070Spatrick   Builder.defineMacro("__PTX__");
168e5dd7070Spatrick   Builder.defineMacro("__NVPTX__");
169*12c85518Srobert   if (Opts.CUDAIsDevice || Opts.OpenMPIsDevice) {
170e5dd7070Spatrick     // Set __CUDA_ARCH__ for the GPU specified.
171e5dd7070Spatrick     std::string CUDAArchCode = [this] {
172e5dd7070Spatrick       switch (GPU) {
173e5dd7070Spatrick       case CudaArch::GFX600:
174e5dd7070Spatrick       case CudaArch::GFX601:
175a9ac8606Spatrick       case CudaArch::GFX602:
176e5dd7070Spatrick       case CudaArch::GFX700:
177e5dd7070Spatrick       case CudaArch::GFX701:
178e5dd7070Spatrick       case CudaArch::GFX702:
179e5dd7070Spatrick       case CudaArch::GFX703:
180e5dd7070Spatrick       case CudaArch::GFX704:
181a9ac8606Spatrick       case CudaArch::GFX705:
182e5dd7070Spatrick       case CudaArch::GFX801:
183e5dd7070Spatrick       case CudaArch::GFX802:
184e5dd7070Spatrick       case CudaArch::GFX803:
185a9ac8606Spatrick       case CudaArch::GFX805:
186e5dd7070Spatrick       case CudaArch::GFX810:
187e5dd7070Spatrick       case CudaArch::GFX900:
188e5dd7070Spatrick       case CudaArch::GFX902:
189e5dd7070Spatrick       case CudaArch::GFX904:
190e5dd7070Spatrick       case CudaArch::GFX906:
191e5dd7070Spatrick       case CudaArch::GFX908:
192e5dd7070Spatrick       case CudaArch::GFX909:
193a9ac8606Spatrick       case CudaArch::GFX90a:
194a9ac8606Spatrick       case CudaArch::GFX90c:
195*12c85518Srobert       case CudaArch::GFX940:
196e5dd7070Spatrick       case CudaArch::GFX1010:
197e5dd7070Spatrick       case CudaArch::GFX1011:
198e5dd7070Spatrick       case CudaArch::GFX1012:
199a9ac8606Spatrick       case CudaArch::GFX1013:
200ec727ea7Spatrick       case CudaArch::GFX1030:
201a9ac8606Spatrick       case CudaArch::GFX1031:
202a9ac8606Spatrick       case CudaArch::GFX1032:
203a9ac8606Spatrick       case CudaArch::GFX1033:
204a9ac8606Spatrick       case CudaArch::GFX1034:
205a9ac8606Spatrick       case CudaArch::GFX1035:
206*12c85518Srobert       case CudaArch::GFX1036:
207*12c85518Srobert       case CudaArch::GFX1100:
208*12c85518Srobert       case CudaArch::GFX1101:
209*12c85518Srobert       case CudaArch::GFX1102:
210*12c85518Srobert       case CudaArch::GFX1103:
211*12c85518Srobert       case CudaArch::Generic:
212e5dd7070Spatrick       case CudaArch::LAST:
213e5dd7070Spatrick         break;
214a9ac8606Spatrick       case CudaArch::UNUSED:
215e5dd7070Spatrick       case CudaArch::UNKNOWN:
216e5dd7070Spatrick         assert(false && "No GPU arch when compiling CUDA device code.");
217e5dd7070Spatrick         return "";
218e5dd7070Spatrick       case CudaArch::SM_20:
219e5dd7070Spatrick         return "200";
220e5dd7070Spatrick       case CudaArch::SM_21:
221e5dd7070Spatrick         return "210";
222e5dd7070Spatrick       case CudaArch::SM_30:
223e5dd7070Spatrick         return "300";
224e5dd7070Spatrick       case CudaArch::SM_32:
225e5dd7070Spatrick         return "320";
226e5dd7070Spatrick       case CudaArch::SM_35:
227e5dd7070Spatrick         return "350";
228e5dd7070Spatrick       case CudaArch::SM_37:
229e5dd7070Spatrick         return "370";
230e5dd7070Spatrick       case CudaArch::SM_50:
231e5dd7070Spatrick         return "500";
232e5dd7070Spatrick       case CudaArch::SM_52:
233e5dd7070Spatrick         return "520";
234e5dd7070Spatrick       case CudaArch::SM_53:
235e5dd7070Spatrick         return "530";
236e5dd7070Spatrick       case CudaArch::SM_60:
237e5dd7070Spatrick         return "600";
238e5dd7070Spatrick       case CudaArch::SM_61:
239e5dd7070Spatrick         return "610";
240e5dd7070Spatrick       case CudaArch::SM_62:
241e5dd7070Spatrick         return "620";
242e5dd7070Spatrick       case CudaArch::SM_70:
243e5dd7070Spatrick         return "700";
244e5dd7070Spatrick       case CudaArch::SM_72:
245e5dd7070Spatrick         return "720";
246e5dd7070Spatrick       case CudaArch::SM_75:
247e5dd7070Spatrick         return "750";
248ec727ea7Spatrick       case CudaArch::SM_80:
249ec727ea7Spatrick         return "800";
250a9ac8606Spatrick       case CudaArch::SM_86:
251a9ac8606Spatrick         return "860";
252*12c85518Srobert       case CudaArch::SM_87:
253*12c85518Srobert         return "870";
254*12c85518Srobert       case CudaArch::SM_89:
255*12c85518Srobert         return "890";
256*12c85518Srobert       case CudaArch::SM_90:
257*12c85518Srobert         return "900";
258e5dd7070Spatrick       }
259e5dd7070Spatrick       llvm_unreachable("unhandled CudaArch");
260e5dd7070Spatrick     }();
261e5dd7070Spatrick     Builder.defineMacro("__CUDA_ARCH__", CUDAArchCode);
262e5dd7070Spatrick   }
263e5dd7070Spatrick }
264e5dd7070Spatrick 
getTargetBuiltins() const265e5dd7070Spatrick ArrayRef<Builtin::Info> NVPTXTargetInfo::getTargetBuiltins() const {
266*12c85518Srobert   return llvm::ArrayRef(BuiltinInfo,
267*12c85518Srobert                         clang::NVPTX::LastTSBuiltin - Builtin::FirstTSBuiltin);
268e5dd7070Spatrick }
269