13#include "llvm/Option/ArgList.h"
14#include "llvm/TargetParser/AArch64TargetParser.h"
15#include "llvm/TargetParser/Host.h"
25 return Triple.isOSDarwin();
30 if (Triple.isTargetMachineMac() &&
31 Triple.getArch() == llvm::Triple::aarch64) {
36 if (Triple.getOS() == llvm::Triple::IOS) {
37 assert(!Triple.isSimulatorEnvironment() &&
"iossim should be mac-like");
39 if (!Triple.isOSVersionLT(26))
42 if (!Triple.isOSVersionLT(18) && !Triple.isArm64e())
46 if (Triple.isWatchOS()) {
47 assert(!Triple.isSimulatorEnvironment() &&
"watchossim should be mac-like");
49 if (Triple.getArch() == llvm::Triple::aarch64_32 || Triple.isArm64e())
50 return Triple.isOSVersionLT(26) ?
"apple-s4" :
"apple-s6";
55 if (Triple.isXROS()) {
57 assert(!Triple.isSimulatorEnvironment() &&
"xrossim should be mac-like");
61 if (Triple.isArm64e())
65 if (Triple.isOSDarwin())
66 return Triple.getArch() == llvm::Triple::aarch64_32 ?
"apple-s4"
76 const llvm::Triple &Triple, Arg *&A) {
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)) {
84 StringRef MArchValue = MArch->getValue();
85 if (MArchValue.split(
"+").first.equals_insensitive(
"native"))
89 CPU = llvm::AArch64::resolveCPUAlias(CPU);
92 return std::string(llvm::sys::getHostCPUName());
101static std::optional<std::string>
104 if (Triple.isTargetMachineMac() && Triple.getArch() == llvm::Triple::aarch64)
116std::optional<std::string>
118 const llvm::Triple &Triple) {
120 if (Arg *A = Args.getLastArg(options::OPT_mtune_EQ)) {
121 StringRef Mtune = A->getValue();
122 std::string TuneCPU = Mtune.lower();
124 if (TuneCPU ==
"native")
125 return std::string(llvm::sys::getHostCPUName());
131 if (Args.getLastArg(options::OPT_mcpu_EQ))
141 llvm::AArch64::ExtensionSet &Extensions,
142 std::optional<std::string> &InvalidArg) {
144 text.split(
Split, StringRef(
"+"), -1,
false);
148 D.
Diag(clang::diag::err_drv_no_neon_modifier);
151 if (!Extensions.parseModifier(
Feature)) {
152 InvalidArg.emplace((
"+" +
Feature).str());
161 llvm::StringMap<bool> HostFeatures = llvm::sys::getHostCPUFeatures();
163 for (
auto &[
Feature, Enabled] : HostFeatures) {
164 std::string F = (
"+" +
Feature).str();
165 if (
auto AE = llvm::AArch64::targetFeatureToExtension(F)) {
167 Extensions.enable(AE->ID);
169 Extensions.disable(AE->ID);
181 llvm::AArch64::ExtensionSet &Extensions,
182 std::optional<std::string> &InvalidArg) {
183 auto [CPU, Features] = Mcpu.split(
"+");
184 const bool IsNative = CPU ==
"native";
187 CPU = llvm::sys::getHostCPUName();
189 const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
190 llvm::AArch64::parseCpu(CPU);
192 InvalidArg.emplace(CPU.str());
196 Extensions.addCPUDefaults(*CpuInfo);
201 if (Features.size() &&
211 llvm::AArch64::ExtensionSet &Extensions,
212 std::optional<std::string> &InvalidArg) {
213 std::string MarchLowerCase = March.lower();
214 auto [CPU, Features] = StringRef(MarchLowerCase).split(
"+");
219 const llvm::AArch64::ArchInfo *ArchInfo =
220 llvm::AArch64::parseArch(CPU);
222 InvalidArg.emplace(CPU.str());
226 Extensions.addArchDefaults(*ArchInfo);
228 if ((Features.size() &&
238 llvm::AArch64::ExtensionSet &Extensions,
239 std::optional<std::string> &InvalidArg) {
240 std::string McpuLowerCase = Mcpu.lower();
247 std::optional<std::string> &InvalidArg) {
249 std::string MtuneLowerCase = Mtune.lower();
250 llvm::AArch64::ExtensionSet Extensions;
257 std::optional<std::string> &InvalidArg) {
262 const llvm::Triple &Triple,
264 std::vector<StringRef> &Features,
265 bool ForAS,
bool ForMultilib) {
268 std::optional<std::string> InvalidArg;
269 llvm::StringRef WaMArch;
270 llvm::AArch64::ExtensionSet Extensions;
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);
280 if (!WaMArch.empty())
283 else if ((A = Args.getLastArg(options::OPT_march_EQ)))
285 Extensions, InvalidArg);
286 else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
297 if (success && (A = Args.getLastArg(options::OPT_mtune_EQ)))
300 else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
310 auto Diag = D.
Diag(diag::err_drv_unsupported_option_argument);
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();
320 Diag << A->getSpelling() << *InvalidArg;
324 if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
325 Extensions.disable(llvm::AArch64::AEK_FP);
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);
333 Extensions.disable(llvm::AArch64::AEK_CRC);
338 Extensions.toLLVMFeatureList(Features);
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);
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) {
370 if (Opt ==
"retbr") {
378 if (Opt ==
"comdat") {
379 DisableComdat =
false;
382 if (Opt ==
"nocomdat") {
383 DisableComdat =
true;
386 D.
Diag(diag::err_drv_unsupported_option_argument)
387 << A->getSpelling() <<
Scope;
393 Features.push_back(
"+harden-sls-retbr");
395 Features.push_back(
"+harden-sls-blr");
397 Features.push_back(
"+harden-sls-nocomdat");
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");
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");
423 if (Args.hasArg(options::OPT_ffixed_x1))
424 Features.push_back(
"+reserve-x1");
426 if (Args.hasArg(options::OPT_ffixed_x2))
427 Features.push_back(
"+reserve-x2");
429 if (Args.hasArg(options::OPT_ffixed_x3))
430 Features.push_back(
"+reserve-x3");
432 if (Args.hasArg(options::OPT_ffixed_x4))
433 Features.push_back(
"+reserve-x4");
435 if (Args.hasArg(options::OPT_ffixed_x5))
436 Features.push_back(
"+reserve-x5");
438 if (Args.hasArg(options::OPT_ffixed_x6))
439 Features.push_back(
"+reserve-x6");
441 if (Args.hasArg(options::OPT_ffixed_x7))
442 Features.push_back(
"+reserve-x7");
444 if (Args.hasArg(options::OPT_ffixed_x9))
445 Features.push_back(
"+reserve-x9");
447 if (Args.hasArg(options::OPT_ffixed_x10))
448 Features.push_back(
"+reserve-x10");
450 if (Args.hasArg(options::OPT_ffixed_x11))
451 Features.push_back(
"+reserve-x11");
453 if (Args.hasArg(options::OPT_ffixed_x12))
454 Features.push_back(
"+reserve-x12");
456 if (Args.hasArg(options::OPT_ffixed_x13))
457 Features.push_back(
"+reserve-x13");
459 if (Args.hasArg(options::OPT_ffixed_x14))
460 Features.push_back(
"+reserve-x14");
462 if (Args.hasArg(options::OPT_ffixed_x15))
463 Features.push_back(
"+reserve-x15");
465 if (Args.hasArg(options::OPT_ffixed_x18))
466 Features.push_back(
"+reserve-x18");
468 if (Args.hasArg(options::OPT_ffixed_x20))
469 Features.push_back(
"+reserve-x20");
471 if (Args.hasArg(options::OPT_ffixed_x21))
472 Features.push_back(
"+reserve-x21");
474 if (Args.hasArg(options::OPT_ffixed_x22))
475 Features.push_back(
"+reserve-x22");
477 if (Args.hasArg(options::OPT_ffixed_x23))
478 Features.push_back(
"+reserve-x23");
480 if (Args.hasArg(options::OPT_ffixed_x24))
481 Features.push_back(
"+reserve-x24");
483 if (Args.hasArg(options::OPT_ffixed_x25))
484 Features.push_back(
"+reserve-x25");
486 if (Args.hasArg(options::OPT_ffixed_x26))
487 Features.push_back(
"+reserve-x26");
489 if (Args.hasArg(options::OPT_ffixed_x27))
490 Features.push_back(
"+reserve-x27");
492 if (Args.hasArg(options::OPT_ffixed_x28))
493 Features.push_back(
"+reserve-x28");
495 if (Args.hasArg(options::OPT_mlr_for_calls_only))
496 Features.push_back(
"+reserve-lr-for-ra");
498 if (Args.hasArg(options::OPT_fcall_saved_x8))
499 Features.push_back(
"+call-saved-x8");
501 if (Args.hasArg(options::OPT_fcall_saved_x9))
502 Features.push_back(
"+call-saved-x9");
504 if (Args.hasArg(options::OPT_fcall_saved_x10))
505 Features.push_back(
"+call-saved-x10");
507 if (Args.hasArg(options::OPT_fcall_saved_x11))
508 Features.push_back(
"+call-saved-x11");
510 if (Args.hasArg(options::OPT_fcall_saved_x12))
511 Features.push_back(
"+call-saved-x12");
513 if (Args.hasArg(options::OPT_fcall_saved_x13))
514 Features.push_back(
"+call-saved-x13");
516 if (Args.hasArg(options::OPT_fcall_saved_x14))
517 Features.push_back(
"+call-saved-x14");
519 if (Args.hasArg(options::OPT_fcall_saved_x15))
520 Features.push_back(
"+call-saved-x15");
522 if (Args.hasArg(options::OPT_fcall_saved_x18))
523 Features.push_back(
"+call-saved-x18");
525 if (Args.hasArg(options::OPT_mno_neg_immediates))
526 Features.push_back(
"+no-neg-immediates");
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");
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()) {
540 Features.push_back(
"+fix-cortex-a53-835769");
541 }
else if (Triple.isOSFuchsia()) {
543 if (
CPU.empty() || CPU ==
"generic" || CPU ==
"cortex-a53")
544 Features.push_back(
"+fix-cortex-a53-835769");
548 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
549 Features.push_back(
"+no-bti-at-return-twice");
554 if (Triple.getArch() != llvm::Triple::aarch64 &&
555 Triple.getArch() != llvm::Triple::aarch64_be)
558 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
561 if (Triple.getOS() != llvm::Triple::UnknownOS)
564 return Triple.getEnvironmentName() ==
"elf";
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.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
The JSON file list parser is used to communicate input to InstallAPI.