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 | |
21 | namespace clang { |
22 | namespace targets { |
23 | |
24 | static 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 | |
52 | class 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 | |
62 | public: |
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 |
Definitions
- ZOSAddressMap
- SystemZTargetInfo
- AddrSpace
- SystemZTargetInfo
- useFP16ConversionIntrinsics
- getGCCRegAliases
- isSPRegName
- convertConstraint
- getClobbers
- getBuiltinVaListKind
- isValidCPUName
- isValidTuneCPUName
- fillValidTuneCPUList
- setCPU
- initFeatureMap
- handleTargetFeatures
- checkCallingConvention
- getABI
- getLongDoubleMangling
- hasBitIntType
- getEHDataRegisterNumber
- hasSjLjLowering
- hardwareInterferenceSizes
- getPointerWidthV
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more