/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/AArch64.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- AArch64.cpp - Implement AArch64 target feature support -----------===// |
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 implements AArch64 TargetInfo objects. |
10 | | // |
11 | | //===----------------------------------------------------------------------===// |
12 | | |
13 | | #include "AArch64.h" |
14 | | #include "clang/Basic/LangOptions.h" |
15 | | #include "clang/Basic/TargetBuiltins.h" |
16 | | #include "clang/Basic/TargetInfo.h" |
17 | | #include "llvm/ADT/ArrayRef.h" |
18 | | #include "llvm/ADT/StringExtras.h" |
19 | | #include "llvm/ADT/StringSwitch.h" |
20 | | #include "llvm/Support/AArch64TargetParser.h" |
21 | | |
22 | | using namespace clang; |
23 | | using namespace clang::targets; |
24 | | |
25 | | const Builtin::Info AArch64TargetInfo::BuiltinInfo[] = { |
26 | | #define BUILTIN(ID, TYPE, ATTRS) \ |
27 | | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
28 | | #include "clang/Basic/BuiltinsNEON.def" |
29 | | |
30 | | #define BUILTIN(ID, TYPE, ATTRS) \ |
31 | | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
32 | | #include "clang/Basic/BuiltinsSVE.def" |
33 | | |
34 | | #define BUILTIN(ID, TYPE, ATTRS) \ |
35 | | {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr}, |
36 | | #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ |
37 | | {#ID, TYPE, ATTRS, nullptr, LANG, nullptr}, |
38 | | #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ |
39 | | {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE}, |
40 | | #include "clang/Basic/BuiltinsAArch64.def" |
41 | | }; |
42 | | |
43 | 2.96k | static StringRef getArchVersionString(llvm::AArch64::ArchKind Kind) { |
44 | 2.96k | switch (Kind) { |
45 | 7 | case llvm::AArch64::ArchKind::ARMV9A: |
46 | 8 | case llvm::AArch64::ArchKind::ARMV9_1A: |
47 | 11 | case llvm::AArch64::ArchKind::ARMV9_2A: |
48 | 15 | case llvm::AArch64::ArchKind::ARMV9_3A: |
49 | 15 | return "9"; |
50 | 2.94k | default: |
51 | 2.94k | return "8"; |
52 | 2.96k | } |
53 | 2.96k | } |
54 | | |
55 | 2.96k | StringRef AArch64TargetInfo::getArchProfile() const { |
56 | 2.96k | switch (ArchKind) { |
57 | 2 | case llvm::AArch64::ArchKind::ARMV8R: |
58 | 2 | return "R"; |
59 | 2.95k | default: |
60 | 2.95k | return "A"; |
61 | 2.96k | } |
62 | 2.96k | } |
63 | | |
64 | | AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, |
65 | | const TargetOptions &Opts) |
66 | 2.97k | : TargetInfo(Triple), ABI("aapcs") { |
67 | 2.97k | if (getTriple().isOSOpenBSD()) { |
68 | 4 | Int64Type = SignedLongLong; |
69 | 4 | IntMaxType = SignedLongLong; |
70 | 2.96k | } else { |
71 | 2.96k | if (!getTriple().isOSDarwin() && !getTriple().isOSNetBSD()2.76k ) |
72 | 2.75k | WCharType = UnsignedInt; |
73 | | |
74 | 2.96k | Int64Type = SignedLong; |
75 | 2.96k | IntMaxType = SignedLong; |
76 | 2.96k | } |
77 | | |
78 | | // All AArch64 implementations support ARMv8 FP, which makes half a legal type. |
79 | 2.97k | HasLegalHalfType = true; |
80 | 2.97k | HasFloat16 = true; |
81 | | |
82 | 2.97k | if (Triple.isArch64Bit()) |
83 | 2.95k | LongWidth = LongAlign = PointerWidth = PointerAlign = 64; |
84 | 16 | else |
85 | 16 | LongWidth = LongAlign = PointerWidth = PointerAlign = 32; |
86 | | |
87 | 2.97k | MaxVectorAlign = 128; |
88 | 2.97k | MaxAtomicInlineWidth = 128; |
89 | 2.97k | MaxAtomicPromoteWidth = 128; |
90 | | |
91 | 2.97k | LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128; |
92 | 2.97k | LongDoubleFormat = &llvm::APFloat::IEEEquad(); |
93 | | |
94 | 2.97k | BFloat16Width = BFloat16Align = 16; |
95 | 2.97k | BFloat16Format = &llvm::APFloat::BFloat(); |
96 | | |
97 | | // Make __builtin_ms_va_list available. |
98 | 2.97k | HasBuiltinMSVaList = true; |
99 | | |
100 | | // Make the SVE types available. Note that this deliberately doesn't |
101 | | // depend on SveMode, since in principle it should be possible to turn |
102 | | // SVE on and off within a translation unit. It should also be possible |
103 | | // to compile the global declaration: |
104 | | // |
105 | | // __SVInt8_t *ptr; |
106 | | // |
107 | | // even without SVE. |
108 | 2.97k | HasAArch64SVETypes = true; |
109 | | |
110 | | // {} in inline assembly are neon specifiers, not assembly variant |
111 | | // specifiers. |
112 | 2.97k | NoAsmVariants = true; |
113 | | |
114 | | // AAPCS gives rules for bitfields. 7.1.7 says: "The container type |
115 | | // contributes to the alignment of the containing aggregate in the same way |
116 | | // a plain (non bit-field) member of that type would, without exception for |
117 | | // zero-sized or anonymous bit-fields." |
118 | 2.97k | assert(UseBitFieldTypeAlignment && "bitfields affect type alignment"); |
119 | 0 | UseZeroLengthBitfieldAlignment = true; |
120 | | |
121 | | // AArch64 targets default to using the ARM C++ ABI. |
122 | 2.97k | TheCXXABI.set(TargetCXXABI::GenericAArch64); |
123 | | |
124 | 2.97k | if (Triple.getOS() == llvm::Triple::Linux) |
125 | 2.37k | this->MCountName = "\01_mcount"; |
126 | 597 | else if (Triple.getOS() == llvm::Triple::UnknownOS) |
127 | 293 | this->MCountName = |
128 | 293 | Opts.EABIVersion == llvm::EABI::GNU ? "\01_mcount"1 : "mcount"292 ; |
129 | 2.97k | } |
130 | | |
131 | 4.16k | StringRef AArch64TargetInfo::getABI() const { return ABI; } |
132 | | |
133 | 302 | bool AArch64TargetInfo::setABI(const std::string &Name) { |
134 | 302 | if (Name != "aapcs" && Name != "darwinpcs"39 ) |
135 | 0 | return false; |
136 | | |
137 | 302 | ABI = Name; |
138 | 302 | return true; |
139 | 302 | } |
140 | | |
141 | | bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, |
142 | | BranchProtectionInfo &BPI, |
143 | 40 | StringRef &Err) const { |
144 | 40 | llvm::ARM::ParsedBranchProtection PBP; |
145 | 40 | if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err)) |
146 | 7 | return false; |
147 | | |
148 | 33 | BPI.SignReturnAddr = |
149 | 33 | llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope) |
150 | 33 | .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf) |
151 | 33 | .Case("all", LangOptions::SignReturnAddressScopeKind::All) |
152 | 33 | .Default(LangOptions::SignReturnAddressScopeKind::None); |
153 | | |
154 | 33 | if (PBP.Key == "a_key") |
155 | 24 | BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey; |
156 | 9 | else |
157 | 9 | BPI.SignKey = LangOptions::SignReturnAddressKeyKind::BKey; |
158 | | |
159 | 33 | BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement; |
160 | 33 | return true; |
161 | 40 | } |
162 | | |
163 | 322 | bool AArch64TargetInfo::isValidCPUName(StringRef Name) const { |
164 | 322 | return Name == "generic" || |
165 | 322 | llvm::AArch64::parseCPUArch(Name) != llvm::AArch64::ArchKind::INVALID60 ; |
166 | 322 | } |
167 | | |
168 | 321 | bool AArch64TargetInfo::setCPU(const std::string &Name) { |
169 | 321 | return isValidCPUName(Name); |
170 | 321 | } |
171 | | |
172 | | void AArch64TargetInfo::fillValidCPUList( |
173 | 2 | SmallVectorImpl<StringRef> &Values) const { |
174 | 2 | llvm::AArch64::fillValidCPUArchList(Values); |
175 | 2 | } |
176 | | |
177 | | void AArch64TargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts, |
178 | 132 | MacroBuilder &Builder) const { |
179 | 132 | Builder.defineMacro("__ARM_FEATURE_QRDMX", "1"); |
180 | 132 | Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1"); |
181 | 132 | Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); |
182 | 132 | } |
183 | | |
184 | | void AArch64TargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts, |
185 | 123 | MacroBuilder &Builder) const { |
186 | | // Also include the ARMv8.1 defines |
187 | 123 | getTargetDefinesARMV81A(Opts, Builder); |
188 | 123 | } |
189 | | |
190 | | void AArch64TargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts, |
191 | 77 | MacroBuilder &Builder) const { |
192 | 77 | Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1"); |
193 | 77 | Builder.defineMacro("__ARM_FEATURE_JCVT", "1"); |
194 | | // Also include the Armv8.2 defines |
195 | 77 | getTargetDefinesARMV82A(Opts, Builder); |
196 | 77 | } |
197 | | |
198 | | void AArch64TargetInfo::getTargetDefinesARMV84A(const LangOptions &Opts, |
199 | 73 | MacroBuilder &Builder) const { |
200 | | // Also include the Armv8.3 defines |
201 | 73 | getTargetDefinesARMV83A(Opts, Builder); |
202 | 73 | } |
203 | | |
204 | | void AArch64TargetInfo::getTargetDefinesARMV85A(const LangOptions &Opts, |
205 | 58 | MacroBuilder &Builder) const { |
206 | 58 | Builder.defineMacro("__ARM_FEATURE_FRINT", "1"); |
207 | | // Also include the Armv8.4 defines |
208 | 58 | getTargetDefinesARMV84A(Opts, Builder); |
209 | 58 | } |
210 | | |
211 | | void AArch64TargetInfo::getTargetDefinesARMV86A(const LangOptions &Opts, |
212 | 24 | MacroBuilder &Builder) const { |
213 | | // Also include the Armv8.5 defines |
214 | | // FIXME: Armv8.6 makes the following extensions mandatory: |
215 | | // - __ARM_FEATURE_BF16 |
216 | | // - __ARM_FEATURE_MATMUL_INT8 |
217 | | // Handle them here. |
218 | 24 | getTargetDefinesARMV85A(Opts, Builder); |
219 | 24 | } |
220 | | |
221 | | void AArch64TargetInfo::getTargetDefinesARMV87A(const LangOptions &Opts, |
222 | 18 | MacroBuilder &Builder) const { |
223 | | // Also include the Armv8.6 defines |
224 | 18 | getTargetDefinesARMV86A(Opts, Builder); |
225 | 18 | } |
226 | | |
227 | | void AArch64TargetInfo::getTargetDefinesARMV88A(const LangOptions &Opts, |
228 | 10 | MacroBuilder &Builder) const { |
229 | | // Also include the Armv8.7 defines |
230 | 10 | getTargetDefinesARMV87A(Opts, Builder); |
231 | 10 | } |
232 | | |
233 | | void AArch64TargetInfo::getTargetDefinesARMV9A(const LangOptions &Opts, |
234 | 7 | MacroBuilder &Builder) const { |
235 | | // Armv9-A maps to Armv8.5-A |
236 | 7 | getTargetDefinesARMV85A(Opts, Builder); |
237 | 7 | } |
238 | | |
239 | | void AArch64TargetInfo::getTargetDefinesARMV91A(const LangOptions &Opts, |
240 | 1 | MacroBuilder &Builder) const { |
241 | | // Armv9.1-A maps to Armv8.6-A |
242 | 1 | getTargetDefinesARMV86A(Opts, Builder); |
243 | 1 | } |
244 | | |
245 | | void AArch64TargetInfo::getTargetDefinesARMV92A(const LangOptions &Opts, |
246 | 3 | MacroBuilder &Builder) const { |
247 | | // Armv9.2-A maps to Armv8.7-A |
248 | 3 | getTargetDefinesARMV87A(Opts, Builder); |
249 | 3 | } |
250 | | |
251 | | void AArch64TargetInfo::getTargetDefinesARMV93A(const LangOptions &Opts, |
252 | 4 | MacroBuilder &Builder) const { |
253 | | // Armv9.3-A maps to Armv8.8-A |
254 | 4 | getTargetDefinesARMV88A(Opts, Builder); |
255 | 4 | } |
256 | | |
257 | | void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts, |
258 | 2.96k | MacroBuilder &Builder) const { |
259 | | // Target identification. |
260 | 2.96k | Builder.defineMacro("__aarch64__"); |
261 | | // For bare-metal. |
262 | 2.96k | if (getTriple().getOS() == llvm::Triple::UnknownOS && |
263 | 2.96k | getTriple().isOSBinFormatELF()288 ) |
264 | 287 | Builder.defineMacro("__ELF__"); |
265 | | |
266 | | // Target properties. |
267 | 2.96k | if (!getTriple().isOSWindows() && getTriple().isArch64Bit()2.90k ) { |
268 | 2.88k | Builder.defineMacro("_LP64"); |
269 | 2.88k | Builder.defineMacro("__LP64__"); |
270 | 2.88k | } |
271 | | |
272 | 2.96k | std::string CodeModel = getTargetOpts().CodeModel; |
273 | 2.96k | if (CodeModel == "default") |
274 | 2.95k | CodeModel = "small"; |
275 | 2.96k | for (char &c : CodeModel) |
276 | 14.7k | c = toupper(c); |
277 | 2.96k | Builder.defineMacro("__AARCH64_CMODEL_" + CodeModel + "__"); |
278 | | |
279 | | // ACLE predefines. Many can only have one possible value on v8 AArch64. |
280 | 2.96k | Builder.defineMacro("__ARM_ACLE", "200"); |
281 | 2.96k | Builder.defineMacro("__ARM_ARCH", getArchVersionString(ArchKind)); |
282 | 2.96k | Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + getArchProfile() + "'"); |
283 | | |
284 | 2.96k | Builder.defineMacro("__ARM_64BIT_STATE", "1"); |
285 | 2.96k | Builder.defineMacro("__ARM_PCS_AAPCS64", "1"); |
286 | 2.96k | Builder.defineMacro("__ARM_ARCH_ISA_A64", "1"); |
287 | | |
288 | 2.96k | Builder.defineMacro("__ARM_FEATURE_CLZ", "1"); |
289 | 2.96k | Builder.defineMacro("__ARM_FEATURE_FMA", "1"); |
290 | 2.96k | Builder.defineMacro("__ARM_FEATURE_LDREX", "0xF"); |
291 | 2.96k | Builder.defineMacro("__ARM_FEATURE_IDIV", "1"); // As specified in ACLE |
292 | 2.96k | Builder.defineMacro("__ARM_FEATURE_DIV"); // For backwards compatibility |
293 | 2.96k | Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1"); |
294 | 2.96k | Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1"); |
295 | | |
296 | 2.96k | Builder.defineMacro("__ARM_ALIGN_MAX_STACK_PWR", "4"); |
297 | | |
298 | | // 0xe implies support for half, single and double precision operations. |
299 | 2.96k | Builder.defineMacro("__ARM_FP", "0xE"); |
300 | | |
301 | | // PCS specifies this for SysV variants, which is all we support. Other ABIs |
302 | | // may choose __ARM_FP16_FORMAT_ALTERNATIVE. |
303 | 2.96k | Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1"); |
304 | 2.96k | Builder.defineMacro("__ARM_FP16_ARGS", "1"); |
305 | | |
306 | 2.96k | if (Opts.UnsafeFPMath) |
307 | 4 | Builder.defineMacro("__ARM_FP_FAST", "1"); |
308 | | |
309 | 2.96k | Builder.defineMacro("__ARM_SIZEOF_WCHAR_T", |
310 | 2.96k | Twine(Opts.WCharSize ? Opts.WCharSize5 : 42.95k )); |
311 | | |
312 | 2.96k | Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1"2 : "4"2.95k ); |
313 | | |
314 | 2.96k | if (FPU & NeonMode) { |
315 | 422 | Builder.defineMacro("__ARM_NEON", "1"); |
316 | | // 64-bit NEON supports half, single and double precision operations. |
317 | 422 | Builder.defineMacro("__ARM_NEON_FP", "0xE"); |
318 | 422 | } |
319 | | |
320 | 2.96k | if (FPU & SveMode) |
321 | 2.04k | Builder.defineMacro("__ARM_FEATURE_SVE", "1"); |
322 | | |
323 | 2.96k | if ((FPU & NeonMode) && (FPU & SveMode)422 ) |
324 | 49 | Builder.defineMacro("__ARM_NEON_SVE_BRIDGE", "1"); |
325 | | |
326 | 2.96k | if (HasSVE2) |
327 | 647 | Builder.defineMacro("__ARM_FEATURE_SVE2", "1"); |
328 | | |
329 | 2.96k | if (HasSVE2 && HasSVE2AES647 ) |
330 | 25 | Builder.defineMacro("__ARM_FEATURE_SVE2_AES", "1"); |
331 | | |
332 | 2.96k | if (HasSVE2 && HasSVE2BitPerm647 ) |
333 | 13 | Builder.defineMacro("__ARM_FEATURE_SVE2_BITPERM", "1"); |
334 | | |
335 | 2.96k | if (HasSVE2 && HasSVE2SHA3647 ) |
336 | 5 | Builder.defineMacro("__ARM_FEATURE_SVE2_SHA3", "1"); |
337 | | |
338 | 2.96k | if (HasSVE2 && HasSVE2SM4647 ) |
339 | 9 | Builder.defineMacro("__ARM_FEATURE_SVE2_SM4", "1"); |
340 | | |
341 | 2.96k | if (HasCRC) |
342 | 20 | Builder.defineMacro("__ARM_FEATURE_CRC32", "1"); |
343 | | |
344 | | // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained feature |
345 | | // macros for AES, SHA2, SHA3 and SM4 |
346 | 2.96k | if (HasAES && HasSHA234 ) |
347 | 33 | Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1"); |
348 | | |
349 | 2.96k | if (HasAES) |
350 | 34 | Builder.defineMacro("__ARM_FEATURE_AES", "1"); |
351 | | |
352 | 2.96k | if (HasSHA2) |
353 | 37 | Builder.defineMacro("__ARM_FEATURE_SHA2", "1"); |
354 | | |
355 | 2.96k | if (HasSHA3) { |
356 | 20 | Builder.defineMacro("__ARM_FEATURE_SHA3", "1"); |
357 | 20 | Builder.defineMacro("__ARM_FEATURE_SHA512", "1"); |
358 | 20 | } |
359 | | |
360 | 2.96k | if (HasSM4) { |
361 | 20 | Builder.defineMacro("__ARM_FEATURE_SM3", "1"); |
362 | 20 | Builder.defineMacro("__ARM_FEATURE_SM4", "1"); |
363 | 20 | } |
364 | | |
365 | 2.96k | if (HasUnaligned) |
366 | 2.95k | Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1"); |
367 | | |
368 | 2.96k | if ((FPU & NeonMode) && HasFullFP16422 ) |
369 | 114 | Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1"); |
370 | 2.96k | if (HasFullFP16) |
371 | 2.11k | Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1"); |
372 | | |
373 | 2.96k | if (HasDotProd) |
374 | 20 | Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1"); |
375 | | |
376 | 2.96k | if (HasMTE) |
377 | 18 | Builder.defineMacro("__ARM_FEATURE_MEMORY_TAGGING", "1"); |
378 | | |
379 | 2.96k | if (HasTME) |
380 | 4 | Builder.defineMacro("__ARM_FEATURE_TME", "1"); |
381 | | |
382 | 2.96k | if (HasMatMul) |
383 | 37 | Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1"); |
384 | | |
385 | 2.96k | if (HasLSE) |
386 | 17 | Builder.defineMacro("__ARM_FEATURE_ATOMICS", "1"); |
387 | | |
388 | 2.96k | if (HasBFloat16) { |
389 | 344 | Builder.defineMacro("__ARM_FEATURE_BF16", "1"); |
390 | 344 | Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1"); |
391 | 344 | Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1"); |
392 | 344 | Builder.defineMacro("__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", "1"); |
393 | 344 | } |
394 | | |
395 | 2.96k | if ((FPU & SveMode) && HasBFloat162.04k ) { |
396 | 312 | Builder.defineMacro("__ARM_FEATURE_SVE_BF16", "1"); |
397 | 312 | } |
398 | | |
399 | 2.96k | if ((FPU & SveMode) && HasMatmulFP642.04k ) |
400 | 61 | Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP64", "1"); |
401 | | |
402 | 2.96k | if ((FPU & SveMode) && HasMatmulFP322.04k ) |
403 | 6 | Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_FP32", "1"); |
404 | | |
405 | 2.96k | if ((FPU & SveMode) && HasMatMul2.04k ) |
406 | 18 | Builder.defineMacro("__ARM_FEATURE_SVE_MATMUL_INT8", "1"); |
407 | | |
408 | 2.96k | if ((FPU & NeonMode) && HasFP16FML422 ) |
409 | 24 | Builder.defineMacro("__ARM_FEATURE_FP16_FML", "1"); |
410 | | |
411 | 2.96k | if (Opts.hasSignReturnAddress()) { |
412 | | // Bitmask: |
413 | | // 0: Protection using the A key |
414 | | // 1: Protection using the B key |
415 | | // 2: Protection including leaf functions |
416 | 15 | unsigned Value = 0; |
417 | | |
418 | 15 | if (Opts.isSignReturnAddressWithAKey()) |
419 | 10 | Value |= (1 << 0); |
420 | 5 | else |
421 | 5 | Value |= (1 << 1); |
422 | | |
423 | 15 | if (Opts.isSignReturnAddressScopeAll()) |
424 | 6 | Value |= (1 << 2); |
425 | | |
426 | 15 | Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", std::to_string(Value)); |
427 | 15 | } |
428 | | |
429 | 2.96k | if (Opts.BranchTargetEnforcement) |
430 | 6 | Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1"); |
431 | | |
432 | 2.96k | if (HasLS64) |
433 | 6 | Builder.defineMacro("__ARM_FEATURE_LS64", "1"); |
434 | | |
435 | 2.96k | if (HasRandGen) |
436 | 2 | Builder.defineMacro("__ARM_FEATURE_RNG", "1"); |
437 | | |
438 | 2.96k | if (HasMOPS) |
439 | 11 | Builder.defineMacro("__ARM_FEATURE_MOPS", "1"); |
440 | | |
441 | 2.96k | switch (ArchKind) { |
442 | 2.82k | default: |
443 | 2.82k | break; |
444 | 2.82k | case llvm::AArch64::ArchKind::ARMV8_1A: |
445 | 9 | getTargetDefinesARMV81A(Opts, Builder); |
446 | 9 | break; |
447 | 46 | case llvm::AArch64::ArchKind::ARMV8_2A: |
448 | 46 | getTargetDefinesARMV82A(Opts, Builder); |
449 | 46 | break; |
450 | 4 | case llvm::AArch64::ArchKind::ARMV8_3A: |
451 | 4 | getTargetDefinesARMV83A(Opts, Builder); |
452 | 4 | break; |
453 | 15 | case llvm::AArch64::ArchKind::ARMV8_4A: |
454 | 15 | getTargetDefinesARMV84A(Opts, Builder); |
455 | 15 | break; |
456 | 27 | case llvm::AArch64::ArchKind::ARMV8_5A: |
457 | 27 | getTargetDefinesARMV85A(Opts, Builder); |
458 | 27 | break; |
459 | 5 | case llvm::AArch64::ArchKind::ARMV8_6A: |
460 | 5 | getTargetDefinesARMV86A(Opts, Builder); |
461 | 5 | break; |
462 | 5 | case llvm::AArch64::ArchKind::ARMV8_7A: |
463 | 5 | getTargetDefinesARMV87A(Opts, Builder); |
464 | 5 | break; |
465 | 6 | case llvm::AArch64::ArchKind::ARMV8_8A: |
466 | 6 | getTargetDefinesARMV88A(Opts, Builder); |
467 | 6 | break; |
468 | 7 | case llvm::AArch64::ArchKind::ARMV9A: |
469 | 7 | getTargetDefinesARMV9A(Opts, Builder); |
470 | 7 | break; |
471 | 1 | case llvm::AArch64::ArchKind::ARMV9_1A: |
472 | 1 | getTargetDefinesARMV91A(Opts, Builder); |
473 | 1 | break; |
474 | 3 | case llvm::AArch64::ArchKind::ARMV9_2A: |
475 | 3 | getTargetDefinesARMV92A(Opts, Builder); |
476 | 3 | break; |
477 | 4 | case llvm::AArch64::ArchKind::ARMV9_3A: |
478 | 4 | getTargetDefinesARMV93A(Opts, Builder); |
479 | 4 | break; |
480 | 2.96k | } |
481 | | |
482 | | // All of the __sync_(bool|val)_compare_and_swap_(1|2|4|8) builtins work. |
483 | 2.96k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1"); |
484 | 2.96k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2"); |
485 | 2.96k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4"); |
486 | 2.96k | Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8"); |
487 | | |
488 | | // Allow detection of fast FMA support. |
489 | 2.96k | Builder.defineMacro("__FP_FAST_FMA", "1"); |
490 | 2.96k | Builder.defineMacro("__FP_FAST_FMAF", "1"); |
491 | | |
492 | 2.96k | if (Opts.VScaleMin && Opts.VScaleMin == Opts.VScaleMax87 ) { |
493 | 78 | Builder.defineMacro("__ARM_FEATURE_SVE_BITS", Twine(Opts.VScaleMin * 128)); |
494 | 78 | Builder.defineMacro("__ARM_FEATURE_SVE_VECTOR_OPERATORS"); |
495 | 78 | } |
496 | 2.96k | } |
497 | | |
498 | 2.96k | ArrayRef<Builtin::Info> AArch64TargetInfo::getTargetBuiltins() const { |
499 | 2.96k | return llvm::makeArrayRef(BuiltinInfo, clang::AArch64::LastTSBuiltin - |
500 | 2.96k | Builtin::FirstTSBuiltin); |
501 | 2.96k | } |
502 | | |
503 | | Optional<std::pair<unsigned, unsigned>> |
504 | 42.8k | AArch64TargetInfo::getVScaleRange(const LangOptions &LangOpts) const { |
505 | 42.8k | if (LangOpts.VScaleMin || LangOpts.VScaleMax42.3k ) |
506 | 505 | return std::pair<unsigned, unsigned>( |
507 | 505 | LangOpts.VScaleMin ? LangOpts.VScaleMin : 10 , LangOpts.VScaleMax); |
508 | | |
509 | 42.3k | if (hasFeature("sve")) |
510 | 30.0k | return std::pair<unsigned, unsigned>(1, 16); |
511 | | |
512 | 12.3k | return None; |
513 | 42.3k | } |
514 | | |
515 | 49.7k | bool AArch64TargetInfo::hasFeature(StringRef Feature) const { |
516 | 49.7k | return llvm::StringSwitch<bool>(Feature) |
517 | 49.7k | .Cases("aarch64", "arm64", "arm", true) |
518 | 49.7k | .Case("neon", FPU & NeonMode) |
519 | 49.7k | .Cases("sve", "sve2", "sve2-bitperm", "sve2-aes", "sve2-sha3", "sve2-sm4", "f64mm", "f32mm", "i8mm", "bf16", FPU & SveMode) |
520 | 49.7k | .Case("ls64", HasLS64) |
521 | 49.7k | .Default(false); |
522 | 49.7k | } |
523 | | |
524 | | bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features, |
525 | 2.97k | DiagnosticsEngine &Diags) { |
526 | 2.97k | FPU = FPUMode; |
527 | 2.97k | HasCRC = false; |
528 | 2.97k | HasAES = false; |
529 | 2.97k | HasSHA2 = false; |
530 | 2.97k | HasSHA3 = false; |
531 | 2.97k | HasSM4 = false; |
532 | 2.97k | HasUnaligned = true; |
533 | 2.97k | HasFullFP16 = false; |
534 | 2.97k | HasDotProd = false; |
535 | 2.97k | HasFP16FML = false; |
536 | 2.97k | HasMTE = false; |
537 | 2.97k | HasTME = false; |
538 | 2.97k | HasLS64 = false; |
539 | 2.97k | HasRandGen = false; |
540 | 2.97k | HasMatMul = false; |
541 | 2.97k | HasBFloat16 = false; |
542 | 2.97k | HasSVE2 = false; |
543 | 2.97k | HasSVE2AES = false; |
544 | 2.97k | HasSVE2SHA3 = false; |
545 | 2.97k | HasSVE2SM4 = false; |
546 | 2.97k | HasSVE2BitPerm = false; |
547 | 2.97k | HasMatmulFP64 = false; |
548 | 2.97k | HasMatmulFP32 = false; |
549 | 2.97k | HasLSE = false; |
550 | 2.97k | HasMOPS = false; |
551 | | |
552 | 2.97k | ArchKind = llvm::AArch64::ArchKind::INVALID; |
553 | | |
554 | 3.75k | for (const auto &Feature : Features) { |
555 | 3.75k | if (Feature == "+neon") |
556 | 422 | FPU |= NeonMode; |
557 | 3.75k | if (Feature == "+sve") { |
558 | 1.41k | FPU |= SveMode; |
559 | 1.41k | HasFullFP16 = true; |
560 | 1.41k | } |
561 | 3.75k | if (Feature == "+sve2") { |
562 | 599 | FPU |= SveMode; |
563 | 599 | HasFullFP16 = true; |
564 | 599 | HasSVE2 = true; |
565 | 599 | } |
566 | 3.75k | if (Feature == "+sve2-aes") { |
567 | 25 | FPU |= SveMode; |
568 | 25 | HasFullFP16 = true; |
569 | 25 | HasSVE2 = true; |
570 | 25 | HasSVE2AES = true; |
571 | 25 | } |
572 | 3.75k | if (Feature == "+sve2-sha3") { |
573 | 5 | FPU |= SveMode; |
574 | 5 | HasFullFP16 = true; |
575 | 5 | HasSVE2 = true; |
576 | 5 | HasSVE2SHA3 = true; |
577 | 5 | } |
578 | 3.75k | if (Feature == "+sve2-sm4") { |
579 | 9 | FPU |= SveMode; |
580 | 9 | HasFullFP16 = true; |
581 | 9 | HasSVE2 = true; |
582 | 9 | HasSVE2SM4 = true; |
583 | 9 | } |
584 | 3.75k | if (Feature == "+sve2-bitperm") { |
585 | 13 | FPU |= SveMode; |
586 | 13 | HasFullFP16 = true; |
587 | 13 | HasSVE2 = true; |
588 | 13 | HasSVE2BitPerm = true; |
589 | 13 | } |
590 | 3.75k | if (Feature == "+f32mm") { |
591 | 6 | FPU |= SveMode; |
592 | 6 | HasMatmulFP32 = true; |
593 | 6 | } |
594 | 3.75k | if (Feature == "+f64mm") { |
595 | 61 | FPU |= SveMode; |
596 | 61 | HasMatmulFP64 = true; |
597 | 61 | } |
598 | 3.75k | if (Feature == "+crc") |
599 | 20 | HasCRC = true; |
600 | 3.75k | if (Feature == "+aes") |
601 | 34 | HasAES = true; |
602 | 3.75k | if (Feature == "+sha2") |
603 | 34 | HasSHA2 = true; |
604 | 3.75k | if (Feature == "+sha3") { |
605 | 20 | HasSHA2 = true; |
606 | 20 | HasSHA3 = true; |
607 | 20 | } |
608 | 3.75k | if (Feature == "+sm4") |
609 | 20 | HasSM4 = true; |
610 | 3.75k | if (Feature == "+strict-align") |
611 | 2 | HasUnaligned = false; |
612 | 3.75k | if (Feature == "+v8a") |
613 | 168 | ArchKind = llvm::AArch64::ArchKind::ARMV8A; |
614 | 3.75k | if (Feature == "+v8.1a") |
615 | 9 | ArchKind = llvm::AArch64::ArchKind::ARMV8_1A; |
616 | 3.75k | if (Feature == "+v8.2a") |
617 | 46 | ArchKind = llvm::AArch64::ArchKind::ARMV8_2A; |
618 | 3.75k | if (Feature == "+v8.3a") |
619 | 4 | ArchKind = llvm::AArch64::ArchKind::ARMV8_3A; |
620 | 3.75k | if (Feature == "+v8.4a") |
621 | 15 | ArchKind = llvm::AArch64::ArchKind::ARMV8_4A; |
622 | 3.75k | if (Feature == "+v8.5a") |
623 | 27 | ArchKind = llvm::AArch64::ArchKind::ARMV8_5A; |
624 | 3.75k | if (Feature == "+v8.6a") |
625 | 5 | ArchKind = llvm::AArch64::ArchKind::ARMV8_6A; |
626 | 3.75k | if (Feature == "+v8.7a") |
627 | 5 | ArchKind = llvm::AArch64::ArchKind::ARMV8_7A; |
628 | 3.75k | if (Feature == "+v8.8a") |
629 | 6 | ArchKind = llvm::AArch64::ArchKind::ARMV8_8A; |
630 | 3.75k | if (Feature == "+v9a") |
631 | 7 | ArchKind = llvm::AArch64::ArchKind::ARMV9A; |
632 | 3.75k | if (Feature == "+v9.1a") |
633 | 1 | ArchKind = llvm::AArch64::ArchKind::ARMV9_1A; |
634 | 3.75k | if (Feature == "+v9.2a") |
635 | 3 | ArchKind = llvm::AArch64::ArchKind::ARMV9_2A; |
636 | 3.75k | if (Feature == "+v9.3a") |
637 | 4 | ArchKind = llvm::AArch64::ArchKind::ARMV9_3A; |
638 | 3.75k | if (Feature == "+v8r") |
639 | 2 | ArchKind = llvm::AArch64::ArchKind::ARMV8R; |
640 | 3.75k | if (Feature == "+fullfp16") |
641 | 72 | HasFullFP16 = true; |
642 | 3.75k | if (Feature == "+dotprod") |
643 | 20 | HasDotProd = true; |
644 | 3.75k | if (Feature == "+fp16fml") |
645 | 27 | HasFP16FML = true; |
646 | 3.75k | if (Feature == "+mte") |
647 | 18 | HasMTE = true; |
648 | 3.75k | if (Feature == "+tme") |
649 | 4 | HasTME = true; |
650 | 3.75k | if (Feature == "+pauth") |
651 | 0 | HasPAuth = true; |
652 | 3.75k | if (Feature == "+i8mm") |
653 | 37 | HasMatMul = true; |
654 | 3.75k | if (Feature == "+bf16") |
655 | 344 | HasBFloat16 = true; |
656 | 3.75k | if (Feature == "+lse") |
657 | 17 | HasLSE = true; |
658 | 3.75k | if (Feature == "+ls64") |
659 | 6 | HasLS64 = true; |
660 | 3.75k | if (Feature == "+rand") |
661 | 2 | HasRandGen = true; |
662 | 3.75k | if (Feature == "+flagm") |
663 | 0 | HasFlagM = true; |
664 | 3.75k | if (Feature == "+mops") |
665 | 11 | HasMOPS = true; |
666 | 3.75k | } |
667 | | |
668 | 2.97k | setDataLayout(); |
669 | | |
670 | 2.97k | return true; |
671 | 2.97k | } |
672 | | |
673 | | TargetInfo::CallingConvCheckResult |
674 | 498 | AArch64TargetInfo::checkCallingConvention(CallingConv CC) const { |
675 | 498 | switch (CC) { |
676 | 4 | case CC_C: |
677 | 324 | case CC_Swift: |
678 | 463 | case CC_SwiftAsync: |
679 | 468 | case CC_PreserveMost: |
680 | 475 | case CC_PreserveAll: |
681 | 475 | case CC_OpenCLKernel: |
682 | 483 | case CC_AArch64VectorCall: |
683 | 491 | case CC_AArch64SVEPCS: |
684 | 498 | case CC_Win64: |
685 | 498 | return CCCR_OK; |
686 | 0 | default: |
687 | 0 | return CCCR_Warning; |
688 | 498 | } |
689 | 498 | } |
690 | | |
691 | 33 | bool AArch64TargetInfo::isCLZForZeroUndef() const { return false; } |
692 | | |
693 | 2.64k | TargetInfo::BuiltinVaListKind AArch64TargetInfo::getBuiltinVaListKind() const { |
694 | 2.64k | return TargetInfo::AArch64ABIBuiltinVaList; |
695 | 2.64k | } |
696 | | |
697 | | const char *const AArch64TargetInfo::GCCRegNames[] = { |
698 | | // 32-bit Integer registers |
699 | | "w0", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", |
700 | | "w12", "w13", "w14", "w15", "w16", "w17", "w18", "w19", "w20", "w21", "w22", |
701 | | "w23", "w24", "w25", "w26", "w27", "w28", "w29", "w30", "wsp", |
702 | | |
703 | | // 64-bit Integer registers |
704 | | "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", |
705 | | "x12", "x13", "x14", "x15", "x16", "x17", "x18", "x19", "x20", "x21", "x22", |
706 | | "x23", "x24", "x25", "x26", "x27", "x28", "fp", "lr", "sp", |
707 | | |
708 | | // 32-bit floating point regsisters |
709 | | "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", |
710 | | "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", |
711 | | "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", |
712 | | |
713 | | // 64-bit floating point regsisters |
714 | | "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", |
715 | | "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", |
716 | | "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", |
717 | | |
718 | | // Neon vector registers |
719 | | "v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11", |
720 | | "v12", "v13", "v14", "v15", "v16", "v17", "v18", "v19", "v20", "v21", "v22", |
721 | | "v23", "v24", "v25", "v26", "v27", "v28", "v29", "v30", "v31", |
722 | | |
723 | | // SVE vector registers |
724 | | "z0", "z1", "z2", "z3", "z4", "z5", "z6", "z7", "z8", "z9", "z10", |
725 | | "z11", "z12", "z13", "z14", "z15", "z16", "z17", "z18", "z19", "z20", "z21", |
726 | | "z22", "z23", "z24", "z25", "z26", "z27", "z28", "z29", "z30", "z31", |
727 | | |
728 | | // SVE predicate registers |
729 | | "p0", "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8", "p9", "p10", |
730 | | "p11", "p12", "p13", "p14", "p15" |
731 | | }; |
732 | | |
733 | 2.00k | ArrayRef<const char *> AArch64TargetInfo::getGCCRegNames() const { |
734 | 2.00k | return llvm::makeArrayRef(GCCRegNames); |
735 | 2.00k | } |
736 | | |
737 | | const TargetInfo::GCCRegAlias AArch64TargetInfo::GCCRegAliases[] = { |
738 | | {{"w31"}, "wsp"}, |
739 | | {{"x31"}, "sp"}, |
740 | | // GCC rN registers are aliases of xN registers. |
741 | | {{"r0"}, "x0"}, |
742 | | {{"r1"}, "x1"}, |
743 | | {{"r2"}, "x2"}, |
744 | | {{"r3"}, "x3"}, |
745 | | {{"r4"}, "x4"}, |
746 | | {{"r5"}, "x5"}, |
747 | | {{"r6"}, "x6"}, |
748 | | {{"r7"}, "x7"}, |
749 | | {{"r8"}, "x8"}, |
750 | | {{"r9"}, "x9"}, |
751 | | {{"r10"}, "x10"}, |
752 | | {{"r11"}, "x11"}, |
753 | | {{"r12"}, "x12"}, |
754 | | {{"r13"}, "x13"}, |
755 | | {{"r14"}, "x14"}, |
756 | | {{"r15"}, "x15"}, |
757 | | {{"r16"}, "x16"}, |
758 | | {{"r17"}, "x17"}, |
759 | | {{"r18"}, "x18"}, |
760 | | {{"r19"}, "x19"}, |
761 | | {{"r20"}, "x20"}, |
762 | | {{"r21"}, "x21"}, |
763 | | {{"r22"}, "x22"}, |
764 | | {{"r23"}, "x23"}, |
765 | | {{"r24"}, "x24"}, |
766 | | {{"r25"}, "x25"}, |
767 | | {{"r26"}, "x26"}, |
768 | | {{"r27"}, "x27"}, |
769 | | {{"r28"}, "x28"}, |
770 | | {{"r29", "x29"}, "fp"}, |
771 | | {{"r30", "x30"}, "lr"}, |
772 | | // The S/D/Q and W/X registers overlap, but aren't really aliases; we |
773 | | // don't want to substitute one of these for a different-sized one. |
774 | | }; |
775 | | |
776 | 828 | ArrayRef<TargetInfo::GCCRegAlias> AArch64TargetInfo::getGCCRegAliases() const { |
777 | 828 | return llvm::makeArrayRef(GCCRegAliases); |
778 | 828 | } |
779 | | |
780 | | bool AArch64TargetInfo::validateAsmConstraint( |
781 | 338 | const char *&Name, TargetInfo::ConstraintInfo &Info) const { |
782 | 338 | switch (*Name) { |
783 | 0 | default: |
784 | 0 | return false; |
785 | 284 | case 'w': // Floating point and SIMD registers (V0-V31) |
786 | 284 | Info.setAllowsRegister(); |
787 | 284 | return true; |
788 | 2 | case 'I': // Constant that can be used with an ADD instruction |
789 | 2 | case 'J': // Constant that can be used with a SUB instruction |
790 | 4 | case 'K': // Constant that can be used with a 32-bit logical instruction |
791 | 6 | case 'L': // Constant that can be used with a 64-bit logical instruction |
792 | 6 | case 'M': // Constant that can be used as a 32-bit MOV immediate |
793 | 6 | case 'N': // Constant that can be used as a 64-bit MOV immediate |
794 | 6 | case 'Y': // Floating point constant zero |
795 | 6 | case 'Z': // Integer constant zero |
796 | 6 | return true; |
797 | 4 | case 'Q': // A memory reference with base register and no offset |
798 | 4 | Info.setAllowsMemory(); |
799 | 4 | return true; |
800 | 2 | case 'S': // A symbolic address |
801 | 2 | Info.setAllowsRegister(); |
802 | 2 | return true; |
803 | 32 | case 'U': |
804 | 32 | if (Name[1] == 'p' && (Name[2] == 'l' || Name[2] == 'a'24 )) { |
805 | | // SVE predicate registers ("Upa"=P0-15, "Upl"=P0-P7) |
806 | 32 | Info.setAllowsRegister(); |
807 | 32 | Name += 2; |
808 | 32 | return true; |
809 | 32 | } |
810 | | // Ump: A memory address suitable for ldp/stp in SI, DI, SF and DF modes. |
811 | | // Utf: A memory address suitable for ldp/stp in TF mode. |
812 | | // Usa: An absolute symbolic address. |
813 | | // Ush: The high part (bits 32:12) of a pc-relative symbolic address. |
814 | | |
815 | | // Better to return an error saying that it's an unrecognised constraint |
816 | | // even if this is a valid constraint in gcc. |
817 | 0 | return false; |
818 | 4 | case 'z': // Zero register, wzr or xzr |
819 | 4 | Info.setAllowsRegister(); |
820 | 4 | return true; |
821 | 0 | case 'x': // Floating point and SIMD registers (V0-V15) |
822 | 0 | Info.setAllowsRegister(); |
823 | 0 | return true; |
824 | 6 | case 'y': // SVE registers (V0-V7) |
825 | 6 | Info.setAllowsRegister(); |
826 | 6 | return true; |
827 | 338 | } |
828 | 0 | return false; |
829 | 338 | } |
830 | | |
831 | | bool AArch64TargetInfo::validateConstraintModifier( |
832 | | StringRef Constraint, char Modifier, unsigned Size, |
833 | 242 | std::string &SuggestedModifier) const { |
834 | | // Strip off constraint modifiers. |
835 | 356 | while (Constraint[0] == '=' || Constraint[0] == '+'250 || Constraint[0] == '&'243 ) |
836 | 114 | Constraint = Constraint.substr(1); |
837 | | |
838 | 242 | switch (Constraint[0]) { |
839 | 185 | default: |
840 | 185 | return true; |
841 | 4 | case 'z': |
842 | 57 | case 'r': { |
843 | 57 | switch (Modifier) { |
844 | 1 | case 'x': |
845 | 7 | case 'w': |
846 | | // For now assume that the person knows what they're |
847 | | // doing with the modifier. |
848 | 7 | return true; |
849 | 50 | default: |
850 | | // By default an 'r' constraint will be in the 'x' |
851 | | // registers. |
852 | 50 | if (Size == 64) |
853 | 26 | return true; |
854 | | |
855 | 24 | if (Size == 512) |
856 | 3 | return HasLS64; |
857 | | |
858 | 21 | SuggestedModifier = "w"; |
859 | 21 | return false; |
860 | 57 | } |
861 | 57 | } |
862 | 242 | } |
863 | 242 | } |
864 | | |
865 | 103 | const char *AArch64TargetInfo::getClobbers() const { return ""; } |
866 | | |
867 | 0 | int AArch64TargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { |
868 | 0 | if (RegNo == 0) |
869 | 0 | return 0; |
870 | 0 | if (RegNo == 1) |
871 | 0 | return 1; |
872 | 0 | return -1; |
873 | 0 | } |
874 | | |
875 | 8.75k | bool AArch64TargetInfo::hasInt128Type() const { return true; } |
876 | | |
877 | | AArch64leTargetInfo::AArch64leTargetInfo(const llvm::Triple &Triple, |
878 | | const TargetOptions &Opts) |
879 | 2.93k | : AArch64TargetInfo(Triple, Opts) {} clang::targets::AArch64leTargetInfo::AArch64leTargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 879 | 2.66k | : AArch64TargetInfo(Triple, Opts) {} |
clang::targets::AArch64leTargetInfo::AArch64leTargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 879 | 272 | : AArch64TargetInfo(Triple, Opts) {} |
|
880 | | |
881 | 2.87k | void AArch64leTargetInfo::setDataLayout() { |
882 | 2.87k | if (getTriple().isOSBinFormatMachO()) { |
883 | 202 | if(getTriple().isArch32Bit()) |
884 | 16 | resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_"); |
885 | 186 | else |
886 | 186 | resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_"); |
887 | 202 | } else |
888 | 2.67k | resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); |
889 | 2.87k | } |
890 | | |
891 | | void AArch64leTargetInfo::getTargetDefines(const LangOptions &Opts, |
892 | 2.92k | MacroBuilder &Builder) const { |
893 | 2.92k | Builder.defineMacro("__AARCH64EL__"); |
894 | 2.92k | AArch64TargetInfo::getTargetDefines(Opts, Builder); |
895 | 2.92k | } |
896 | | |
897 | | AArch64beTargetInfo::AArch64beTargetInfo(const llvm::Triple &Triple, |
898 | | const TargetOptions &Opts) |
899 | 33 | : AArch64TargetInfo(Triple, Opts) {} clang::targets::AArch64beTargetInfo::AArch64beTargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 899 | 10 | : AArch64TargetInfo(Triple, Opts) {} |
clang::targets::AArch64beTargetInfo::AArch64beTargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 899 | 23 | : AArch64TargetInfo(Triple, Opts) {} |
|
900 | | |
901 | | void AArch64beTargetInfo::getTargetDefines(const LangOptions &Opts, |
902 | 33 | MacroBuilder &Builder) const { |
903 | 33 | Builder.defineMacro("__AARCH64EB__"); |
904 | 33 | Builder.defineMacro("__AARCH_BIG_ENDIAN"); |
905 | 33 | Builder.defineMacro("__ARM_BIG_ENDIAN"); |
906 | 33 | AArch64TargetInfo::getTargetDefines(Opts, Builder); |
907 | 33 | } |
908 | | |
909 | 33 | void AArch64beTargetInfo::setDataLayout() { |
910 | 33 | assert(!getTriple().isOSBinFormatMachO()); |
911 | 0 | resetDataLayout("E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); |
912 | 33 | } |
913 | | |
914 | | WindowsARM64TargetInfo::WindowsARM64TargetInfo(const llvm::Triple &Triple, |
915 | | const TargetOptions &Opts) |
916 | 59 | : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) { |
917 | | |
918 | | // This is an LLP64 platform. |
919 | | // int:4, long:4, long long:8, long double:8. |
920 | 59 | IntWidth = IntAlign = 32; |
921 | 59 | LongWidth = LongAlign = 32; |
922 | 59 | DoubleAlign = LongLongAlign = 64; |
923 | 59 | LongDoubleWidth = LongDoubleAlign = 64; |
924 | 59 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
925 | 59 | IntMaxType = SignedLongLong; |
926 | 59 | Int64Type = SignedLongLong; |
927 | 59 | SizeType = UnsignedLongLong; |
928 | 59 | PtrDiffType = SignedLongLong; |
929 | 59 | IntPtrType = SignedLongLong; |
930 | 59 | } clang::targets::WindowsARM64TargetInfo::WindowsARM64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 916 | 59 | : WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) { | 917 | | | 918 | | // This is an LLP64 platform. | 919 | | // int:4, long:4, long long:8, long double:8. | 920 | 59 | IntWidth = IntAlign = 32; | 921 | 59 | LongWidth = LongAlign = 32; | 922 | 59 | DoubleAlign = LongLongAlign = 64; | 923 | 59 | LongDoubleWidth = LongDoubleAlign = 64; | 924 | 59 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 925 | 59 | IntMaxType = SignedLongLong; | 926 | 59 | Int64Type = SignedLongLong; | 927 | 59 | SizeType = UnsignedLongLong; | 928 | 59 | PtrDiffType = SignedLongLong; | 929 | 59 | IntPtrType = SignedLongLong; | 930 | 59 | } |
Unexecuted instantiation: clang::targets::WindowsARM64TargetInfo::WindowsARM64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) |
931 | | |
932 | 59 | void WindowsARM64TargetInfo::setDataLayout() { |
933 | 59 | resetDataLayout(Triple.isOSBinFormatMachO() |
934 | 59 | ? "e-m:o-i64:64-i128:128-n32:64-S128"1 |
935 | 59 | : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"58 , |
936 | 59 | Triple.isOSBinFormatMachO() ? "_"1 : ""58 ); |
937 | 59 | } |
938 | | |
939 | | TargetInfo::BuiltinVaListKind |
940 | 61 | WindowsARM64TargetInfo::getBuiltinVaListKind() const { |
941 | 61 | return TargetInfo::CharPtrBuiltinVaList; |
942 | 61 | } |
943 | | |
944 | | TargetInfo::CallingConvCheckResult |
945 | 63 | WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const { |
946 | 63 | switch (CC) { |
947 | 3 | case CC_X86StdCall: |
948 | 5 | case CC_X86ThisCall: |
949 | 6 | case CC_X86FastCall: |
950 | 7 | case CC_X86VectorCall: |
951 | 7 | return CCCR_Ignore; |
952 | 43 | case CC_C: |
953 | 43 | case CC_OpenCLKernel: |
954 | 48 | case CC_PreserveMost: |
955 | 53 | case CC_PreserveAll: |
956 | 55 | case CC_Swift: |
957 | 56 | case CC_SwiftAsync: |
958 | 56 | case CC_Win64: |
959 | 56 | return CCCR_OK; |
960 | 0 | default: |
961 | 0 | return CCCR_Warning; |
962 | 63 | } |
963 | 63 | } |
964 | | |
965 | | MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(const llvm::Triple &Triple, |
966 | | const TargetOptions &Opts) |
967 | 56 | : WindowsARM64TargetInfo(Triple, Opts) { |
968 | 56 | TheCXXABI.set(TargetCXXABI::Microsoft); |
969 | 56 | } Unexecuted instantiation: clang::targets::MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) clang::targets::MicrosoftARM64TargetInfo::MicrosoftARM64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 967 | 56 | : WindowsARM64TargetInfo(Triple, Opts) { | 968 | 56 | TheCXXABI.set(TargetCXXABI::Microsoft); | 969 | 56 | } |
|
970 | | |
971 | | void MicrosoftARM64TargetInfo::getTargetDefines(const LangOptions &Opts, |
972 | 56 | MacroBuilder &Builder) const { |
973 | 56 | WindowsARM64TargetInfo::getTargetDefines(Opts, Builder); |
974 | 56 | Builder.defineMacro("_M_ARM64", "1"); |
975 | 56 | } |
976 | | |
977 | | TargetInfo::CallingConvKind |
978 | 110 | MicrosoftARM64TargetInfo::getCallingConvKind(bool ClangABICompat4) const { |
979 | 110 | return CCK_MicrosoftWin64; |
980 | 110 | } |
981 | | |
982 | 163 | unsigned MicrosoftARM64TargetInfo::getMinGlobalAlign(uint64_t TypeSize) const { |
983 | 163 | unsigned Align = WindowsARM64TargetInfo::getMinGlobalAlign(TypeSize); |
984 | | |
985 | | // MSVC does size based alignment for arm64 based on alignment section in |
986 | | // below document, replicate that to keep alignment consistent with object |
987 | | // files compiled by MSVC. |
988 | | // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions |
989 | 163 | if (TypeSize >= 512) { // TypeSize >= 64 bytes |
990 | 10 | Align = std::max(Align, 128u); // align type at least 16 bytes |
991 | 153 | } else if (TypeSize >= 64) { // TypeSize >= 8 bytes |
992 | 57 | Align = std::max(Align, 64u); // align type at least 8 butes |
993 | 96 | } else if (TypeSize >= 16) { // TypeSize >= 2 bytes |
994 | 45 | Align = std::max(Align, 32u); // align type at least 4 bytes |
995 | 45 | } |
996 | 163 | return Align; |
997 | 163 | } |
998 | | |
999 | | MinGWARM64TargetInfo::MinGWARM64TargetInfo(const llvm::Triple &Triple, |
1000 | | const TargetOptions &Opts) |
1001 | 3 | : WindowsARM64TargetInfo(Triple, Opts) { |
1002 | 3 | TheCXXABI.set(TargetCXXABI::GenericAArch64); |
1003 | 3 | } Unexecuted instantiation: clang::targets::MinGWARM64TargetInfo::MinGWARM64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) clang::targets::MinGWARM64TargetInfo::MinGWARM64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 1001 | 3 | : WindowsARM64TargetInfo(Triple, Opts) { | 1002 | 3 | TheCXXABI.set(TargetCXXABI::GenericAArch64); | 1003 | 3 | } |
|
1004 | | |
1005 | | DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(const llvm::Triple &Triple, |
1006 | | const TargetOptions &Opts) |
1007 | 201 | : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { |
1008 | 201 | Int64Type = SignedLongLong; |
1009 | 201 | if (getTriple().isArch32Bit()) |
1010 | 16 | IntMaxType = SignedLongLong; |
1011 | | |
1012 | 201 | WCharType = SignedInt; |
1013 | 201 | UseSignedCharForObjCBool = false; |
1014 | | |
1015 | 201 | LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; |
1016 | 201 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); |
1017 | | |
1018 | 201 | UseZeroLengthBitfieldAlignment = false; |
1019 | | |
1020 | 201 | if (getTriple().isArch32Bit()) { |
1021 | 16 | UseBitFieldTypeAlignment = false; |
1022 | 16 | ZeroLengthBitfieldBoundary = 32; |
1023 | 16 | UseZeroLengthBitfieldAlignment = true; |
1024 | 16 | TheCXXABI.set(TargetCXXABI::WatchOS); |
1025 | 16 | } else |
1026 | 185 | TheCXXABI.set(TargetCXXABI::AppleARM64); |
1027 | 201 | } Unexecuted instantiation: clang::targets::DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) clang::targets::DarwinAArch64TargetInfo::DarwinAArch64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 1007 | 201 | : DarwinTargetInfo<AArch64leTargetInfo>(Triple, Opts) { | 1008 | 201 | Int64Type = SignedLongLong; | 1009 | 201 | if (getTriple().isArch32Bit()) | 1010 | 16 | IntMaxType = SignedLongLong; | 1011 | | | 1012 | 201 | WCharType = SignedInt; | 1013 | 201 | UseSignedCharForObjCBool = false; | 1014 | | | 1015 | 201 | LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64; | 1016 | 201 | LongDoubleFormat = &llvm::APFloat::IEEEdouble(); | 1017 | | | 1018 | 201 | UseZeroLengthBitfieldAlignment = false; | 1019 | | | 1020 | 201 | if (getTriple().isArch32Bit()) { | 1021 | 16 | UseBitFieldTypeAlignment = false; | 1022 | 16 | ZeroLengthBitfieldBoundary = 32; | 1023 | 16 | UseZeroLengthBitfieldAlignment = true; | 1024 | 16 | TheCXXABI.set(TargetCXXABI::WatchOS); | 1025 | 16 | } else | 1026 | 185 | TheCXXABI.set(TargetCXXABI::AppleARM64); | 1027 | 201 | } |
|
1028 | | |
1029 | | void DarwinAArch64TargetInfo::getOSDefines(const LangOptions &Opts, |
1030 | | const llvm::Triple &Triple, |
1031 | 201 | MacroBuilder &Builder) const { |
1032 | 201 | Builder.defineMacro("__AARCH64_SIMD__"); |
1033 | 201 | if (Triple.isArch32Bit()) |
1034 | 16 | Builder.defineMacro("__ARM64_ARCH_8_32__"); |
1035 | 185 | else |
1036 | 185 | Builder.defineMacro("__ARM64_ARCH_8__"); |
1037 | 201 | Builder.defineMacro("__ARM_NEON__"); |
1038 | 201 | Builder.defineMacro("__LITTLE_ENDIAN__"); |
1039 | 201 | Builder.defineMacro("__REGISTER_PREFIX__", ""); |
1040 | 201 | Builder.defineMacro("__arm64", "1"); |
1041 | 201 | Builder.defineMacro("__arm64__", "1"); |
1042 | | |
1043 | 201 | if (Triple.isArm64e()) |
1044 | 5 | Builder.defineMacro("__arm64e__", "1"); |
1045 | | |
1046 | 201 | getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); |
1047 | 201 | } |
1048 | | |
1049 | | TargetInfo::BuiltinVaListKind |
1050 | 213 | DarwinAArch64TargetInfo::getBuiltinVaListKind() const { |
1051 | 213 | return TargetInfo::CharPtrBuiltinVaList; |
1052 | 213 | } |
1053 | | |
1054 | | // 64-bit RenderScript is aarch64 |
1055 | | RenderScript64TargetInfo::RenderScript64TargetInfo(const llvm::Triple &Triple, |
1056 | | const TargetOptions &Opts) |
1057 | | : AArch64leTargetInfo(llvm::Triple("aarch64", Triple.getVendorName(), |
1058 | | Triple.getOSName(), |
1059 | | Triple.getEnvironmentName()), |
1060 | 1 | Opts) { |
1061 | 1 | IsRenderScriptTarget = true; |
1062 | 1 | } clang::targets::RenderScript64TargetInfo::RenderScript64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 1060 | 1 | Opts) { | 1061 | 1 | IsRenderScriptTarget = true; | 1062 | 1 | } |
Unexecuted instantiation: clang::targets::RenderScript64TargetInfo::RenderScript64TargetInfo(llvm::Triple const&, clang::TargetOptions const&) |
1063 | | |
1064 | | void RenderScript64TargetInfo::getTargetDefines(const LangOptions &Opts, |
1065 | 1 | MacroBuilder &Builder) const { |
1066 | 1 | Builder.defineMacro("__RENDERSCRIPT__"); |
1067 | 1 | AArch64leTargetInfo::getTargetDefines(Opts, Builder); |
1068 | 1 | } |