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