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