1//===--- SystemZ.h - Declare SystemZ target feature support -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file declares SystemZ TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H
14#define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H
15
16#include "clang/Basic/TargetInfo.h"
17#include "clang/Basic/TargetOptions.h"
18#include "llvm/Support/Compiler.h"
19#include "llvm/TargetParser/Triple.h"
20
21namespace clang {
22namespace targets {
23
24static const unsigned ZOSAddressMap[] = {
25 0, // Default
26 0, // opencl_global
27 0, // opencl_local
28 0, // opencl_constant
29 0, // opencl_private
30 0, // opencl_generic
31 0, // opencl_global_device
32 0, // opencl_global_host
33 0, // cuda_device
34 0, // cuda_constant
35 0, // cuda_shared
36 0, // sycl_global
37 0, // sycl_global_device
38 0, // sycl_global_host
39 0, // sycl_local
40 0, // sycl_private
41 0, // ptr32_sptr
42 1, // ptr32_uptr
43 0, // ptr64
44 0, // hlsl_groupshared
45 0, // hlsl_constant
46 0, // hlsl_private
47 0, // hlsl_device
48 0, // hlsl_input
49 0 // wasm_funcref
50};
51
52class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
53
54 static const char *const GCCRegNames[];
55 int ISARevision;
56 bool HasTransactionalExecution;
57 bool HasVector;
58 bool SoftFloat;
59 bool UnalignedSymbols;
60 enum AddrSpace { ptr32 = 1 };
61
62public:
63 SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
64 : TargetInfo(Triple), ISARevision(getISARevision(Name: "z10")),
65 HasTransactionalExecution(false), HasVector(false), SoftFloat(false),
66 UnalignedSymbols(false) {
67 IntMaxType = SignedLong;
68 Int64Type = SignedLong;
69 IntWidth = IntAlign = 32;
70 LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;
71 Int128Align = 64;
72 PointerWidth = PointerAlign = 64;
73 LongDoubleWidth = 128;
74 LongDoubleAlign = 64;
75 LongDoubleFormat = &llvm::APFloat::IEEEquad();
76 DefaultAlignForAttributeAligned = 64;
77 MinGlobalAlign = 16;
78 HasUnalignedAccess = true;
79 if (Triple.isOSzOS()) {
80 if (Triple.isArch64Bit()) {
81 AddrSpaceMap = &ZOSAddressMap;
82 }
83 TLSSupported = false;
84 // All vector types are default aligned on an 8-byte boundary, even if the
85 // vector facility is not available. That is different from Linux.
86 MaxVectorAlign = 64;
87 // Compared to Linux/ELF, the data layout differs only in some details:
88 // - name mangling is GOFF.
89 // - 32 bit pointers, either as default or special address space
90 resetDataLayout(DL: "E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"
91 "a:8:16-n32:64");
92 } else {
93 TLSSupported = true;
94 resetDataLayout(DL: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"
95 "-v128:64-a:8:16-n32:64");
96 }
97 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128;
98
99 // True if the backend supports operations on the half LLVM IR type.
100 // By setting this to false, conversions will happen for _Float16 around
101 // a statement by default, with operations done in float. However, if
102 // -ffloat16-excess-precision=none is given, no conversions will be made
103 // and instead the backend will promote each half operation to float
104 // individually.
105 HasLegalHalfType = false;
106 // Support _Float16.
107 HasFloat16 = true;
108
109 HasStrictFP = true;
110 }
111
112 unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override;
113
114 bool useFP16ConversionIntrinsics() const override { return false; }
115
116 void getTargetDefines(const LangOptions &Opts,
117 MacroBuilder &Builder) const override;
118
119 llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
120
121 ArrayRef<const char *> getGCCRegNames() const override;
122
123 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
124 // No aliases.
125 return {};
126 }
127
128 ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;
129
130 bool isSPRegName(StringRef RegName) const override {
131 return RegName == "r15";
132 }
133
134 bool validateAsmConstraint(const char *&Name,
135 TargetInfo::ConstraintInfo &info) const override;
136
137 std::string convertConstraint(const char *&Constraint) const override {
138 switch (Constraint[0]) {
139 case 'p': // Keep 'p' constraint.
140 return std::string("p");
141 case 'Z':
142 switch (Constraint[1]) {
143 case 'Q': // Address with base and unsigned 12-bit displacement
144 case 'R': // Likewise, plus an index
145 case 'S': // Address with base and signed 20-bit displacement
146 case 'T': // Likewise, plus an index
147 // "^" hints llvm that this is a 2 letter constraint.
148 // "Constraint++" is used to promote the string iterator
149 // to the next constraint.
150 return std::string("^") + std::string(Constraint++, 2);
151 default:
152 break;
153 }
154 break;
155 default:
156 break;
157 }
158 return TargetInfo::convertConstraint(Constraint);
159 }
160
161 std::string_view getClobbers() const override {
162 // FIXME: Is this really right?
163 return "";
164 }
165
166 BuiltinVaListKind getBuiltinVaListKind() const override {
167 return TargetInfo::SystemZBuiltinVaList;
168 }
169
170 int getISARevision(StringRef Name) const;
171
172 bool isValidCPUName(StringRef Name) const override {
173 return getISARevision(Name) != -1;
174 }
175
176 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
177
178 bool isValidTuneCPUName(StringRef Name) const override {
179 return isValidCPUName(Name);
180 }
181
182 void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override {
183 fillValidCPUList(Values);
184 }
185
186 bool setCPU(const std::string &Name) override {
187 ISARevision = getISARevision(Name);
188 return ISARevision != -1;
189 }
190
191 bool
192 initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
193 StringRef CPU,
194 const std::vector<std::string> &FeaturesVec) const override {
195 int ISARevision = getISARevision(Name: CPU);
196 if (ISARevision >= 10)
197 Features["transactional-execution"] = true;
198 if (ISARevision >= 11)
199 Features["vector"] = true;
200 if (ISARevision >= 12)
201 Features["vector-enhancements-1"] = true;
202 if (ISARevision >= 13)
203 Features["vector-enhancements-2"] = true;
204 if (ISARevision >= 14)
205 Features["nnp-assist"] = true;
206 if (ISARevision >= 15) {
207 Features["miscellaneous-extensions-4"] = true;
208 Features["vector-enhancements-3"] = true;
209 }
210 return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec: FeaturesVec);
211 }
212
213 bool handleTargetFeatures(std::vector<std::string> &Features,
214 DiagnosticsEngine &Diags) override {
215 HasTransactionalExecution = false;
216 HasVector = false;
217 SoftFloat = false;
218 UnalignedSymbols = false;
219 for (const auto &Feature : Features) {
220 if (Feature == "+transactional-execution")
221 HasTransactionalExecution = true;
222 else if (Feature == "+vector")
223 HasVector = true;
224 else if (Feature == "+soft-float")
225 SoftFloat = true;
226 else if (Feature == "+unaligned-symbols")
227 UnalignedSymbols = true;
228 }
229 HasVector &= !SoftFloat;
230
231 // If we use the vector ABI, vector types are 64-bit aligned. The
232 // DataLayout string is always set to this alignment as it is not a
233 // requirement that it follows the alignment emitted by the front end. It
234 // is assumed generally that the Datalayout should reflect only the
235 // target triple and not any specific feature.
236 if (HasVector && !getTriple().isOSzOS())
237 MaxVectorAlign = 64;
238
239 return true;
240 }
241
242 bool hasFeature(StringRef Feature) const override;
243
244 CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
245 switch (CC) {
246 case CC_C:
247 case CC_Swift:
248 case CC_DeviceKernel:
249 return CCCR_OK;
250 case CC_SwiftAsync:
251 return CCCR_Error;
252 default:
253 return CCCR_Warning;
254 }
255 }
256
257 StringRef getABI() const override {
258 if (HasVector)
259 return "vector";
260 return "";
261 }
262
263 const char *getLongDoubleMangling() const override { return "g"; }
264
265 bool hasBitIntType() const override { return true; }
266
267 int getEHDataRegisterNumber(unsigned RegNo) const override {
268 return RegNo < 4 ? 6 + RegNo : -1;
269 }
270
271 bool hasSjLjLowering() const override { return true; }
272
273 std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {
274 return std::make_pair(x: 256, y: 256);
275 }
276 uint64_t getPointerWidthV(LangAS AddrSpace) const override {
277 return (getTriple().isOSzOS() && getTriple().isArch64Bit() &&
278 getTargetAddressSpace(AS: AddrSpace) == ptr32)
279 ? 32
280 : PointerWidth;
281 }
282
283 uint64_t getPointerAlignV(LangAS AddrSpace) const override {
284 return getPointerWidthV(AddrSpace);
285 }
286};
287} // namespace targets
288} // namespace clang
289#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H
290

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of clang/lib/Basic/Targets/SystemZ.h