clang 23.0.0git
AArch64.cpp
Go to the documentation of this file.
1//===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- 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#include "AArch64.h"
11#include "clang/Driver/Driver.h"
13#include "llvm/Option/ArgList.h"
14#include "llvm/TargetParser/AArch64TargetParser.h"
15#include "llvm/TargetParser/Host.h"
16
17using namespace clang::driver;
18using namespace clang::driver::tools;
19using namespace clang;
20using namespace llvm::opt;
21
22/// \returns true if the given triple can determine the default CPU type even
23/// if -arch is not specified.
24static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) {
25 return Triple.isOSDarwin();
26}
27
28/// \return the target CPU LLVM name based on the target triple.
29static std::string getAArch64TargetCPUByTriple(const llvm::Triple &Triple) {
30 if (Triple.isTargetMachineMac() &&
31 Triple.getArch() == llvm::Triple::aarch64) {
32 // Apple Silicon macs default to M1 CPUs.
33 return "apple-m1";
34 }
35
36 if (Triple.getOS() == llvm::Triple::IOS) {
37 assert(!Triple.isSimulatorEnvironment() && "iossim should be mac-like");
38 // iOS 26 only runs on apple-a12 and later CPUs.
39 if (!Triple.isOSVersionLT(26))
40 return "apple-a12";
41 // arm64 (non-e) iOS 18 only runs on apple-a10 and later CPUs.
42 if (!Triple.isOSVersionLT(18) && !Triple.isArm64e())
43 return "apple-a10";
44 }
45
46 if (Triple.isWatchOS()) {
47 assert(!Triple.isSimulatorEnvironment() && "watchossim should be mac-like");
48 // arm64_32/arm64e watchOS requires S4 before watchOS 26, S6 after.
49 if (Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e())
50 return Triple.isOSVersionLT(26) ? "apple-s4" : "apple-s6";
51 // arm64 (non-e, non-32) watchOS comes later, and requires S9 anyway.
52 return "apple-s9";
53 }
54
55 if (Triple.isXROS()) {
56 // The xrOS simulator runs on M1 as well, it should have been covered above.
57 assert(!Triple.isSimulatorEnvironment() && "xrossim should be mac-like");
58 return "apple-a12";
59 }
60 // arm64e requires v8.3a and only runs on apple-a12 and later CPUs.
61 if (Triple.isArm64e())
62 return "apple-a12";
63
64 // Make sure we pick the appropriate Apple CPU when targetting a Darwin OS.
65 if (Triple.isOSDarwin())
66 return Triple.getArch() == llvm::Triple::aarch64_32 ? "apple-s4"
67 : "apple-a7";
68
69 return "generic";
70}
71
72/// \return the (LLVM) name of the AArch64 CPU we are targeting. Set \p A to the
73/// Arg corresponding to the -mcpu argument if it is provided, or to nullptr
74/// otherwise.
75std::string aarch64::getAArch64TargetCPU(const ArgList &Args,
76 const llvm::Triple &Triple, Arg *&A) {
77 std::string CPU;
78 // If we have -mcpu, use that.
79 if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
80 StringRef Mcpu = A->getValue();
81 CPU = Mcpu.split("+").first.lower();
82 } else if (const Arg *MArch = Args.getLastArg(options::OPT_march_EQ)) {
83 // Otherwise, use -march=native if specified.
84 StringRef MArchValue = MArch->getValue();
85 if (MArchValue.split("+").first.equals_insensitive("native"))
86 CPU = "native";
87 }
88
89 CPU = llvm::AArch64::resolveCPUAlias(CPU);
90
91 if (CPU == "native")
92 return std::string(llvm::sys::getHostCPUName());
93
94 if (CPU.size())
95 return CPU;
96
97 return getAArch64TargetCPUByTriple(Triple);
98}
99
100/// \return the target tune CPU LLVM name based on the target triple.
101static std::optional<std::string>
102getAArch64TargetTuneCPUByTriple(const llvm::Triple &Triple) {
103 // Apple Silicon macs default to the latest available target for tuning.
104 if (Triple.isTargetMachineMac() && Triple.getArch() == llvm::Triple::aarch64)
105 return "apple-m5";
106
107 return std::nullopt;
108}
109
110/// \return the LLVM name of the AArch64 tune CPU we should target.
111/// Returns std::nullopt if no tune CPU should be specified.
112///
113/// Note: Unlike getAArch64TargetCPU, this function does not resolve CPU
114/// aliases, as it is currently not used for target architecture feature
115/// collection, but defers it to the backend.
116std::optional<std::string>
117aarch64::getAArch64TargetTuneCPU(const llvm::opt::ArgList &Args,
118 const llvm::Triple &Triple) {
119 // -mtune has highest priority, then -mcpu
120 if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
121 StringRef Mtune = A->getValue();
122 std::string TuneCPU = Mtune.lower();
123
124 if (TuneCPU == "native")
125 return std::string(llvm::sys::getHostCPUName());
126
127 return TuneCPU;
128 }
129
130 // If -mcpu is present, let the backend mirror it for tuning
131 if (Args.getLastArg(options::OPT_mcpu_EQ))
132 return std::nullopt;
133
134 // If both -mtune and -mcpu are not present, try infer tune CPU from the
135 // target triple, or let the backend mirror the inferred target CPU for tuning
136 return getAArch64TargetTuneCPUByTriple(Triple);
137}
138
139// Decode AArch64 features from string like +[no]featureA+[no]featureB+...
140static bool DecodeAArch64Features(const Driver &D, StringRef text,
141 llvm::AArch64::ExtensionSet &Extensions,
142 std::optional<std::string> &InvalidArg) {
144 text.split(Split, StringRef("+"), -1, false);
145
146 for (StringRef Feature : Split) {
147 if (Feature == "neon" || Feature == "noneon") {
148 D.Diag(clang::diag::err_drv_no_neon_modifier);
149 continue;
150 }
151 if (!Extensions.parseModifier(Feature)) {
152 InvalidArg.emplace(("+" + Feature).str());
153 return false;
154 }
155 }
156
157 return true;
158}
159
160static bool DecodeAArch64HostFeatures(llvm::AArch64::ExtensionSet &Extensions) {
161 llvm::StringMap<bool> HostFeatures = llvm::sys::getHostCPUFeatures();
162
163 for (auto &[Feature, Enabled] : HostFeatures) {
164 std::string F = ("+" + Feature).str();
165 if (auto AE = llvm::AArch64::targetFeatureToExtension(F)) {
166 if (Enabled)
167 Extensions.enable(AE->ID);
168 else
169 Extensions.disable(AE->ID);
170 continue;
171 }
172 return false;
173 }
174
175 return true;
176}
177
178// Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
179// decode CPU and feature.
180static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu,
181 llvm::AArch64::ExtensionSet &Extensions,
182 std::optional<std::string> &InvalidArg) {
183 auto [CPU, Features] = Mcpu.split("+");
184 const bool IsNative = CPU == "native";
185
186 if (IsNative)
187 CPU = llvm::sys::getHostCPUName();
188
189 const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
190 llvm::AArch64::parseCpu(CPU);
191 if (!CpuInfo) {
192 InvalidArg.emplace(CPU.str());
193 return false;
194 }
195
196 Extensions.addCPUDefaults(*CpuInfo);
197
198 if (IsNative && !DecodeAArch64HostFeatures(Extensions))
199 return false;
200
201 if (Features.size() &&
202 !DecodeAArch64Features(D, Features, Extensions, InvalidArg))
203 return false;
204
205 return true;
206}
207
208static bool
209getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
210 const ArgList &Args,
211 llvm::AArch64::ExtensionSet &Extensions,
212 std::optional<std::string> &InvalidArg) {
213 std::string MarchLowerCase = March.lower();
214 auto [CPU, Features] = StringRef(MarchLowerCase).split("+");
215
216 if (CPU == "native")
217 return DecodeAArch64Mcpu(D, MarchLowerCase, Extensions, InvalidArg);
218
219 const llvm::AArch64::ArchInfo *ArchInfo =
220 llvm::AArch64::parseArch(CPU);
221 if (!ArchInfo) {
222 InvalidArg.emplace(CPU.str());
223 return false;
224 }
225
226 Extensions.addArchDefaults(*ArchInfo);
227
228 if ((Features.size() &&
229 !DecodeAArch64Features(D, Features, Extensions, InvalidArg)))
230 return false;
231
232 return true;
233}
234
235static bool
236getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
237 const ArgList &Args,
238 llvm::AArch64::ExtensionSet &Extensions,
239 std::optional<std::string> &InvalidArg) {
240 std::string McpuLowerCase = Mcpu.lower();
241 return DecodeAArch64Mcpu(D, McpuLowerCase, Extensions, InvalidArg);
242}
243
244static bool
246 const ArgList &Args,
247 std::optional<std::string> &InvalidArg) {
248 // Check CPU name is valid, but ignore any extensions on it.
249 std::string MtuneLowerCase = Mtune.lower();
250 llvm::AArch64::ExtensionSet Extensions;
251 return DecodeAArch64Mcpu(D, MtuneLowerCase, Extensions, InvalidArg);
252}
253
254static bool
256 const ArgList &Args,
257 std::optional<std::string> &InvalidArg) {
258 return getAArch64MicroArchFeaturesFromMtune(D, Mcpu, Args, InvalidArg);
259}
260
262 const llvm::Triple &Triple,
263 const ArgList &Args,
264 std::vector<StringRef> &Features,
265 bool ForAS, bool ForMultilib) {
266 Arg *A;
267 bool success = true;
268 std::optional<std::string> InvalidArg;
269 llvm::StringRef WaMArch;
270 llvm::AArch64::ExtensionSet Extensions;
271 if (ForAS)
272 for (const auto *A :
273 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
274 for (StringRef Value : A->getValues())
275 if (Value.starts_with("-march="))
276 WaMArch = Value.substr(7);
277 // Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or
278 // "-Xassembler -march" is detected. Otherwise it may return false
279 // and causes Clang to error out.
280 if (!WaMArch.empty())
281 success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Extensions,
282 InvalidArg);
283 else if ((A = Args.getLastArg(options::OPT_march_EQ)))
284 success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args,
285 Extensions, InvalidArg);
286 else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
287 success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Extensions,
288 InvalidArg);
289 else if (isCPUDeterminedByTriple(Triple))
291 D, getAArch64TargetCPUByTriple(Triple), Args, Extensions, InvalidArg);
292 else
293 // Default to 'A' profile if the architecture is not specified.
294 success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Extensions,
295 InvalidArg);
296
297 if (success && (A = Args.getLastArg(options::OPT_mtune_EQ)))
298 success = getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args,
299 InvalidArg);
300 else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
301 success =
302 getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, InvalidArg);
303 else if (success) {
304 if (auto TuneCPU = getAArch64TargetTuneCPUByTriple(Triple))
305 success =
306 getAArch64MicroArchFeaturesFromMtune(D, *TuneCPU, Args, InvalidArg);
307 }
308
309 if (!success) {
310 auto Diag = D.Diag(diag::err_drv_unsupported_option_argument);
311 // If "-Wa,-march=" is used, 'WaMArch' will contain the argument's value,
312 // while 'A' is uninitialized. Only dereference 'A' in the other case.
313 if (!WaMArch.empty() && InvalidArg)
314 Diag << "-march=" << *InvalidArg;
315 else if (!WaMArch.empty())
316 Diag << "-march=" << WaMArch;
317 else if (!InvalidArg)
318 Diag << A->getSpelling() << A->getValue();
319 else
320 Diag << A->getSpelling() << *InvalidArg;
321 }
322
323 // -mgeneral-regs-only disables all floating-point features.
324 if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
325 Extensions.disable(llvm::AArch64::AEK_FP);
326 }
327
328 // En/disable crc
329 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
330 if (A->getOption().matches(options::OPT_mcrc))
331 Extensions.enable(llvm::AArch64::AEK_CRC);
332 else
333 Extensions.disable(llvm::AArch64::AEK_CRC);
334 }
335
336 // At this point all hardware features are decided, so convert the extensions
337 // set to a feature list.
338 Extensions.toLLVMFeatureList(Features);
339
340 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
341 StringRef Mtp = A->getValue();
342 if (Mtp == "el3" || Mtp == "tpidr_el3")
343 Features.push_back("+tpidr-el3");
344 else if (Mtp == "el2" || Mtp == "tpidr_el2")
345 Features.push_back("+tpidr-el2");
346 else if (Mtp == "el1" || Mtp == "tpidr_el1")
347 Features.push_back("+tpidr-el1");
348 else if (Mtp == "tpidrro_el0")
349 Features.push_back("+tpidrro-el0");
350 else if (Mtp != "el0" && Mtp != "tpidr_el0")
351 D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
352 }
353
354 // Enable/disable straight line speculation hardening.
355 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
356 StringRef Scope = A->getValue();
357 bool EnableRetBr = false;
358 bool EnableBlr = false;
359 bool DisableComdat = false;
360 if (Scope != "none") {
362 Scope.split(Opts, ",");
363 for (auto Opt : Opts) {
364 Opt = Opt.trim();
365 if (Opt == "all") {
366 EnableBlr = true;
367 EnableRetBr = true;
368 continue;
369 }
370 if (Opt == "retbr") {
371 EnableRetBr = true;
372 continue;
373 }
374 if (Opt == "blr") {
375 EnableBlr = true;
376 continue;
377 }
378 if (Opt == "comdat") {
379 DisableComdat = false;
380 continue;
381 }
382 if (Opt == "nocomdat") {
383 DisableComdat = true;
384 continue;
385 }
386 D.Diag(diag::err_drv_unsupported_option_argument)
387 << A->getSpelling() << Scope;
388 break;
389 }
390 }
391
392 if (EnableRetBr)
393 Features.push_back("+harden-sls-retbr");
394 if (EnableBlr)
395 Features.push_back("+harden-sls-blr");
396 if (DisableComdat) {
397 Features.push_back("+harden-sls-nocomdat");
398 }
399 }
400
401 if (Arg *A = Args.getLastArg(
402 options::OPT_mstrict_align, options::OPT_mno_strict_align,
403 options::OPT_mno_unaligned_access, options::OPT_munaligned_access)) {
404 if (A->getOption().matches(options::OPT_mstrict_align) ||
405 A->getOption().matches(options::OPT_mno_unaligned_access))
406 Features.push_back("+strict-align");
407 } else if (Triple.isOSOpenBSD())
408 Features.push_back("+strict-align");
409
410 // Generate execute-only output (no data access to code sections).
411 // This only makes sense for the compiler, not for the assembler.
412 // It's not needed for multilib selection and may hide an unused
413 // argument diagnostic if the code is always run.
414 if (!ForAS && !ForMultilib) {
415 if (Arg *A = Args.getLastArg(options::OPT_mexecute_only,
416 options::OPT_mno_execute_only)) {
417 if (A->getOption().matches(options::OPT_mexecute_only)) {
418 Features.push_back("+execute-only");
419 }
420 }
421 }
422
423 if (Args.hasArg(options::OPT_ffixed_x1))
424 Features.push_back("+reserve-x1");
425
426 if (Args.hasArg(options::OPT_ffixed_x2))
427 Features.push_back("+reserve-x2");
428
429 if (Args.hasArg(options::OPT_ffixed_x3))
430 Features.push_back("+reserve-x3");
431
432 if (Args.hasArg(options::OPT_ffixed_x4))
433 Features.push_back("+reserve-x4");
434
435 if (Args.hasArg(options::OPT_ffixed_x5))
436 Features.push_back("+reserve-x5");
437
438 if (Args.hasArg(options::OPT_ffixed_x6))
439 Features.push_back("+reserve-x6");
440
441 if (Args.hasArg(options::OPT_ffixed_x7))
442 Features.push_back("+reserve-x7");
443
444 if (Args.hasArg(options::OPT_ffixed_x9))
445 Features.push_back("+reserve-x9");
446
447 if (Args.hasArg(options::OPT_ffixed_x10))
448 Features.push_back("+reserve-x10");
449
450 if (Args.hasArg(options::OPT_ffixed_x11))
451 Features.push_back("+reserve-x11");
452
453 if (Args.hasArg(options::OPT_ffixed_x12))
454 Features.push_back("+reserve-x12");
455
456 if (Args.hasArg(options::OPT_ffixed_x13))
457 Features.push_back("+reserve-x13");
458
459 if (Args.hasArg(options::OPT_ffixed_x14))
460 Features.push_back("+reserve-x14");
461
462 if (Args.hasArg(options::OPT_ffixed_x15))
463 Features.push_back("+reserve-x15");
464
465 if (Args.hasArg(options::OPT_ffixed_x18))
466 Features.push_back("+reserve-x18");
467
468 if (Args.hasArg(options::OPT_ffixed_x20))
469 Features.push_back("+reserve-x20");
470
471 if (Args.hasArg(options::OPT_ffixed_x21))
472 Features.push_back("+reserve-x21");
473
474 if (Args.hasArg(options::OPT_ffixed_x22))
475 Features.push_back("+reserve-x22");
476
477 if (Args.hasArg(options::OPT_ffixed_x23))
478 Features.push_back("+reserve-x23");
479
480 if (Args.hasArg(options::OPT_ffixed_x24))
481 Features.push_back("+reserve-x24");
482
483 if (Args.hasArg(options::OPT_ffixed_x25))
484 Features.push_back("+reserve-x25");
485
486 if (Args.hasArg(options::OPT_ffixed_x26))
487 Features.push_back("+reserve-x26");
488
489 if (Args.hasArg(options::OPT_ffixed_x27))
490 Features.push_back("+reserve-x27");
491
492 if (Args.hasArg(options::OPT_ffixed_x28))
493 Features.push_back("+reserve-x28");
494
495 if (Args.hasArg(options::OPT_mlr_for_calls_only))
496 Features.push_back("+reserve-lr-for-ra");
497
498 if (Args.hasArg(options::OPT_fcall_saved_x8))
499 Features.push_back("+call-saved-x8");
500
501 if (Args.hasArg(options::OPT_fcall_saved_x9))
502 Features.push_back("+call-saved-x9");
503
504 if (Args.hasArg(options::OPT_fcall_saved_x10))
505 Features.push_back("+call-saved-x10");
506
507 if (Args.hasArg(options::OPT_fcall_saved_x11))
508 Features.push_back("+call-saved-x11");
509
510 if (Args.hasArg(options::OPT_fcall_saved_x12))
511 Features.push_back("+call-saved-x12");
512
513 if (Args.hasArg(options::OPT_fcall_saved_x13))
514 Features.push_back("+call-saved-x13");
515
516 if (Args.hasArg(options::OPT_fcall_saved_x14))
517 Features.push_back("+call-saved-x14");
518
519 if (Args.hasArg(options::OPT_fcall_saved_x15))
520 Features.push_back("+call-saved-x15");
521
522 if (Args.hasArg(options::OPT_fcall_saved_x18))
523 Features.push_back("+call-saved-x18");
524
525 if (Args.hasArg(options::OPT_mno_neg_immediates))
526 Features.push_back("+no-neg-immediates");
527
528 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
529 options::OPT_mno_fix_cortex_a53_835769)) {
530 if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
531 Features.push_back("+fix-cortex-a53-835769");
532 else
533 Features.push_back("-fix-cortex-a53-835769");
534 } else if (Extensions.BaseArch &&
535 Extensions.BaseArch->Version.getMajor() == 8 &&
536 Extensions.BaseArch->Version.getMinor() == 0) {
537 if (Triple.isAndroid() || Triple.isOHOSFamily()) {
538 // Enabled A53 errata (835769) workaround by default on android, providing
539 // that the architecture allows running on a cortex-a53.
540 Features.push_back("+fix-cortex-a53-835769");
541 } else if (Triple.isOSFuchsia()) {
542 std::string CPU = getCPUName(D, Args, Triple);
543 if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53")
544 Features.push_back("+fix-cortex-a53-835769");
545 }
546 }
547
548 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
549 Features.push_back("+no-bti-at-return-twice");
550}
551
552/// Is the triple {aarch64.aarch64_be}-none-elf?
553bool aarch64::isAArch64BareMetal(const llvm::Triple &Triple) {
554 if (Triple.getArch() != llvm::Triple::aarch64 &&
555 Triple.getArch() != llvm::Triple::aarch64_be)
556 return false;
557
558 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
559 return false;
560
561 if (Triple.getOS() != llvm::Triple::UnknownOS)
562 return false;
563
564 return Triple.getEnvironmentName() == "elf";
565}
static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, llvm::AArch64::ExtensionSet &Extensions, std::optional< std::string > &InvalidArg)
Definition AArch64.cpp:180
static bool DecodeAArch64HostFeatures(llvm::AArch64::ExtensionSet &Extensions)
Definition AArch64.cpp:160
static std::string getAArch64TargetCPUByTriple(const llvm::Triple &Triple)
Definition AArch64.cpp:29
static bool getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, const ArgList &Args, llvm::AArch64::ExtensionSet &Extensions, std::optional< std::string > &InvalidArg)
Definition AArch64.cpp:209
static bool DecodeAArch64Features(const Driver &D, StringRef text, llvm::AArch64::ExtensionSet &Extensions, std::optional< std::string > &InvalidArg)
Definition AArch64.cpp:140
static bool getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, const ArgList &Args, std::optional< std::string > &InvalidArg)
Definition AArch64.cpp:245
static bool getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, const ArgList &Args, std::optional< std::string > &InvalidArg)
Definition AArch64.cpp:255
static bool isCPUDeterminedByTriple(const llvm::Triple &Triple)
Definition AArch64.cpp:24
static bool getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, const ArgList &Args, llvm::AArch64::ExtensionSet &Extensions, std::optional< std::string > &InvalidArg)
Definition AArch64.cpp:236
static std::optional< std::string > getAArch64TargetTuneCPUByTriple(const llvm::Triple &Triple)
Definition AArch64.cpp:102
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition Driver.h:99
DiagnosticBuilder Diag(unsigned DiagID) const
Definition Driver.h:169
bool isAArch64BareMetal(const llvm::Triple &Triple)
Is the triple {aarch64.aarch64_be}-none-elf?
Definition AArch64.cpp:553
void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features, bool ForAS, bool ForMultilib=false)
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, llvm::opt::Arg *&A)
std::optional< std::string > getAArch64TargetTuneCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
Definition AArch64.cpp:117
std::string getCPUName(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &T, bool FromAs=false)
The JSON file list parser is used to communicate input to InstallAPI.