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 | class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { |
25 | |
26 | static const char *const GCCRegNames[]; |
27 | std::string CPU; |
28 | int ISARevision; |
29 | bool HasTransactionalExecution; |
30 | bool HasVector; |
31 | bool SoftFloat; |
32 | bool UnalignedSymbols; |
33 | |
34 | public: |
35 | SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &) |
36 | : TargetInfo(Triple), CPU("z10" ), ISARevision(8), |
37 | HasTransactionalExecution(false), HasVector(false), SoftFloat(false), |
38 | UnalignedSymbols(false) { |
39 | IntMaxType = SignedLong; |
40 | Int64Type = SignedLong; |
41 | IntWidth = IntAlign = 32; |
42 | LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64; |
43 | Int128Align = 64; |
44 | PointerWidth = PointerAlign = 64; |
45 | LongDoubleWidth = 128; |
46 | LongDoubleAlign = 64; |
47 | LongDoubleFormat = &llvm::APFloat::IEEEquad(); |
48 | DefaultAlignForAttributeAligned = 64; |
49 | MinGlobalAlign = 16; |
50 | HasUnalignedAccess = true; |
51 | if (Triple.isOSzOS()) { |
52 | TLSSupported = false; |
53 | // All vector types are default aligned on an 8-byte boundary, even if the |
54 | // vector facility is not available. That is different from Linux. |
55 | MaxVectorAlign = 64; |
56 | // Compared to Linux/ELF, the data layout differs only in some details: |
57 | // - name mangling is GOFF. |
58 | // - 32 bit pointers, either as default or special address space |
59 | resetDataLayout(DL: "E-m:l-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-" |
60 | "a:8:16-n32:64" ); |
61 | } else { |
62 | TLSSupported = true; |
63 | resetDataLayout(DL: "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64" |
64 | "-v128:64-a:8:16-n32:64" ); |
65 | } |
66 | MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128; |
67 | HasStrictFP = true; |
68 | } |
69 | |
70 | unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override; |
71 | |
72 | void getTargetDefines(const LangOptions &Opts, |
73 | MacroBuilder &Builder) const override; |
74 | |
75 | ArrayRef<Builtin::Info> getTargetBuiltins() const override; |
76 | |
77 | ArrayRef<const char *> getGCCRegNames() const override; |
78 | |
79 | ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { |
80 | // No aliases. |
81 | return std::nullopt; |
82 | } |
83 | |
84 | ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override; |
85 | |
86 | bool isSPRegName(StringRef RegName) const override { |
87 | return RegName == "r15" ; |
88 | } |
89 | |
90 | bool validateAsmConstraint(const char *&Name, |
91 | TargetInfo::ConstraintInfo &info) const override; |
92 | |
93 | std::string convertConstraint(const char *&Constraint) const override { |
94 | switch (Constraint[0]) { |
95 | case 'p': // Keep 'p' constraint. |
96 | return std::string("p" ); |
97 | case 'Z': |
98 | switch (Constraint[1]) { |
99 | case 'Q': // Address with base and unsigned 12-bit displacement |
100 | case 'R': // Likewise, plus an index |
101 | case 'S': // Address with base and signed 20-bit displacement |
102 | case 'T': // Likewise, plus an index |
103 | // "^" hints llvm that this is a 2 letter constraint. |
104 | // "Constraint++" is used to promote the string iterator |
105 | // to the next constraint. |
106 | return std::string("^" ) + std::string(Constraint++, 2); |
107 | default: |
108 | break; |
109 | } |
110 | break; |
111 | default: |
112 | break; |
113 | } |
114 | return TargetInfo::convertConstraint(Constraint); |
115 | } |
116 | |
117 | std::string_view getClobbers() const override { |
118 | // FIXME: Is this really right? |
119 | return "" ; |
120 | } |
121 | |
122 | BuiltinVaListKind getBuiltinVaListKind() const override { |
123 | return TargetInfo::SystemZBuiltinVaList; |
124 | } |
125 | |
126 | int getISARevision(StringRef Name) const; |
127 | |
128 | bool isValidCPUName(StringRef Name) const override { |
129 | return getISARevision(Name) != -1; |
130 | } |
131 | |
132 | void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; |
133 | |
134 | bool isValidTuneCPUName(StringRef Name) const override { |
135 | return isValidCPUName(Name); |
136 | } |
137 | |
138 | void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override { |
139 | fillValidCPUList(Values); |
140 | } |
141 | |
142 | bool setCPU(const std::string &Name) override { |
143 | CPU = Name; |
144 | ISARevision = getISARevision(Name: CPU); |
145 | return ISARevision != -1; |
146 | } |
147 | |
148 | bool |
149 | initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, |
150 | StringRef CPU, |
151 | const std::vector<std::string> &FeaturesVec) const override { |
152 | int ISARevision = getISARevision(Name: CPU); |
153 | if (ISARevision >= 10) |
154 | Features["transactional-execution" ] = true; |
155 | if (ISARevision >= 11) |
156 | Features["vector" ] = true; |
157 | if (ISARevision >= 12) |
158 | Features["vector-enhancements-1" ] = true; |
159 | if (ISARevision >= 13) |
160 | Features["vector-enhancements-2" ] = true; |
161 | if (ISARevision >= 14) |
162 | Features["nnp-assist" ] = true; |
163 | return TargetInfo::initFeatureMap(Features, Diags, CPU, FeatureVec: FeaturesVec); |
164 | } |
165 | |
166 | bool handleTargetFeatures(std::vector<std::string> &Features, |
167 | DiagnosticsEngine &Diags) override { |
168 | HasTransactionalExecution = false; |
169 | HasVector = false; |
170 | SoftFloat = false; |
171 | UnalignedSymbols = false; |
172 | for (const auto &Feature : Features) { |
173 | if (Feature == "+transactional-execution" ) |
174 | HasTransactionalExecution = true; |
175 | else if (Feature == "+vector" ) |
176 | HasVector = true; |
177 | else if (Feature == "+soft-float" ) |
178 | SoftFloat = true; |
179 | else if (Feature == "+unaligned-symbols" ) |
180 | UnalignedSymbols = true; |
181 | } |
182 | HasVector &= !SoftFloat; |
183 | |
184 | // If we use the vector ABI, vector types are 64-bit aligned. The |
185 | // DataLayout string is always set to this alignment as it is not a |
186 | // requirement that it follows the alignment emitted by the front end. It |
187 | // is assumed generally that the Datalayout should reflect only the |
188 | // target triple and not any specific feature. |
189 | if (HasVector && !getTriple().isOSzOS()) |
190 | MaxVectorAlign = 64; |
191 | |
192 | return true; |
193 | } |
194 | |
195 | bool hasFeature(StringRef Feature) const override; |
196 | |
197 | CallingConvCheckResult checkCallingConvention(CallingConv CC) const override { |
198 | switch (CC) { |
199 | case CC_C: |
200 | case CC_Swift: |
201 | case CC_OpenCLKernel: |
202 | return CCCR_OK; |
203 | case CC_SwiftAsync: |
204 | return CCCR_Error; |
205 | default: |
206 | return CCCR_Warning; |
207 | } |
208 | } |
209 | |
210 | StringRef getABI() const override { |
211 | if (HasVector) |
212 | return "vector" ; |
213 | return "" ; |
214 | } |
215 | |
216 | const char *getLongDoubleMangling() const override { return "g" ; } |
217 | |
218 | bool hasBitIntType() const override { return true; } |
219 | |
220 | int getEHDataRegisterNumber(unsigned RegNo) const override { |
221 | return RegNo < 4 ? 6 + RegNo : -1; |
222 | } |
223 | |
224 | std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override { |
225 | return std::make_pair(x: 256, y: 256); |
226 | } |
227 | }; |
228 | } // namespace targets |
229 | } // namespace clang |
230 | #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H |
231 | |