10#include "../CommonArgs.h"
14#include "llvm/Option/ArgList.h"
15#include "llvm/TargetParser/AArch64TargetParser.h"
16#include "llvm/TargetParser/Host.h"
26 return Triple.isOSDarwin();
33 const llvm::Triple &Triple, Arg *&A) {
36 if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
37 StringRef Mcpu = A->getValue();
38 CPU = Mcpu.split(
"+").first.lower();
41 CPU = llvm::AArch64::resolveCPUAlias(CPU);
45 return std::string(llvm::sys::getHostCPUName());
50 if (Triple.isTargetMachineMac() &&
51 Triple.getArch() == llvm::Triple::aarch64) {
57 if (Triple.isArm64e())
62 if (Args.getLastArg(options::OPT_arch) || Triple.isOSDarwin())
63 return Triple.getArch() == llvm::Triple::aarch64_32 ?
"apple-s4"
71 std::vector<StringRef> &Features,
72 const llvm::AArch64::ArchInfo &ArchInfo) {
74 text.split(
Split, StringRef(
"+"), -1,
false);
76 for (StringRef Feature :
Split) {
77 StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
78 if (!FeatureName.empty())
79 Features.push_back(FeatureName);
80 else if (Feature ==
"neon" || Feature ==
"noneon")
81 D.
Diag(clang::diag::err_drv_no_neon_modifier);
87 if (Feature ==
"sme") {
88 Features.push_back(
"+bf16");
89 }
else if (Feature ==
"nosme") {
90 Features.push_back(
"-sme-f64f64");
91 Features.push_back(
"-sme-i16i64");
92 }
else if (Feature ==
"sme-f64f64") {
93 Features.push_back(
"+sme");
94 Features.push_back(
"+bf16");
95 }
else if (Feature ==
"sme-i16i64") {
96 Features.push_back(
"+sme");
97 Features.push_back(
"+bf16");
98 }
else if (Feature ==
"nobf16") {
99 Features.push_back(
"-sme");
100 Features.push_back(
"-sme-f64f64");
101 Features.push_back(
"-sme-i16i64");
104 if (Feature ==
"sve2")
105 Features.push_back(
"+sve");
106 else if (Feature ==
"sve2-bitperm" || Feature ==
"sve2-sha3" ||
107 Feature ==
"sve2-aes" || Feature ==
"sve2-sm4") {
108 Features.push_back(
"+sve");
109 Features.push_back(
"+sve2");
110 }
else if (Feature ==
"nosve") {
111 Features.push_back(
"-sve2");
112 Features.push_back(
"-sve2-bitperm");
113 Features.push_back(
"-sve2-sha3");
114 Features.push_back(
"-sve2-aes");
115 Features.push_back(
"-sve2-sm4");
116 }
else if (Feature ==
"nosve2") {
117 Features.push_back(
"-sve2-bitperm");
118 Features.push_back(
"-sve2-sha3");
119 Features.push_back(
"-sve2-aes");
120 Features.push_back(
"-sve2-sm4");
125 if ((ArchInfo == llvm::AArch64::ARMV8_6A ||
126 ArchInfo == llvm::AArch64::ARMV8_7A ||
127 ArchInfo == llvm::AArch64::ARMV8_8A ||
128 ArchInfo == llvm::AArch64::ARMV8_9A ||
129 ArchInfo == llvm::AArch64::ARMV9_1A ||
130 ArchInfo == llvm::AArch64::ARMV9_2A ||
131 ArchInfo == llvm::AArch64::ARMV9_3A ||
132 ArchInfo == llvm::AArch64::ARMV9_4A) &&
134 Features.push_back(
"+f32mm");
142 std::vector<StringRef> &Features) {
143 std::pair<StringRef, StringRef>
Split = Mcpu.split(
"+");
145 const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A;
148 CPU = llvm::sys::getHostCPUName();
150 if (CPU ==
"generic") {
151 Features.push_back(
"+neon");
153 const std::optional<llvm::AArch64::CpuInfo> CpuInfo =
154 llvm::AArch64::parseCpu(CPU);
157 ArchInfo = &CpuInfo->Arch;
159 Features.push_back(ArchInfo->ArchFeature);
161 auto Extension = CpuInfo->getImpliedExtensions();
162 if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
166 if (
Split.second.size() &&
176 std::vector<StringRef> &Features) {
177 std::string MarchLowerCase = March.lower();
178 std::pair<StringRef, StringRef>
Split = StringRef(MarchLowerCase).split(
"+");
180 std::optional <llvm::AArch64::ArchInfo> ArchInfo =
181 llvm::AArch64::parseArch(
Split.first);
182 if (
Split.first ==
"native")
183 ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str());
186 Features.push_back(ArchInfo->ArchFeature);
191 if ((*ArchInfo == llvm::AArch64::ARMV9A ||
192 *ArchInfo == llvm::AArch64::ARMV9_1A ||
193 *ArchInfo == llvm::AArch64::ARMV9_2A)) {
194 Features.push_back(
"+sve");
195 Features.push_back(
"+sve2");
198 if ((
Split.second.size() &&
208 std::vector<StringRef> &Features) {
210 std::string McpuLowerCase = Mcpu.lower();
220 std::vector<StringRef> &Features) {
221 std::string MtuneLowerCase = Mtune.lower();
223 std::vector<StringRef> MtuneFeatures;
229 if (MtuneLowerCase ==
"native")
230 MtuneLowerCase = std::string(llvm::sys::getHostCPUName());
231 if (MtuneLowerCase ==
"cyclone" ||
232 StringRef(MtuneLowerCase).startswith(
"apple")) {
233 Features.push_back(
"+zcm");
234 Features.push_back(
"+zcz");
242 std::vector<StringRef> &Features) {
244 std::vector<StringRef> DecodedFeature;
245 std::string McpuLowerCase = Mcpu.lower();
253 const llvm::Triple &Triple,
255 std::vector<StringRef> &Features,
260 Features.push_back(
"+neon");
261 llvm::StringRef WaMArch;
264 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
265 for (StringRef
Value : A->getValues())
266 if (
Value.startswith(
"-march="))
267 WaMArch =
Value.substr(7);
271 if (!WaMArch.empty())
273 else if ((A = Args.getLastArg(options::OPT_march_EQ)))
275 else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
284 if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
287 else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
296 auto Diag = D.
Diag(diag::err_drv_unsupported_option_argument);
299 if (!WaMArch.empty())
300 Diag <<
"-march=" << WaMArch;
302 Diag << A->getSpelling() << A->getValue();
305 if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
306 Features.push_back(
"-fp-armv8");
307 Features.push_back(
"-crypto");
308 Features.push_back(
"-neon");
311 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
312 StringRef Mtp = A->getValue();
313 if (Mtp ==
"el3" || Mtp ==
"tpidr_el3")
314 Features.push_back(
"+tpidr-el3");
315 else if (Mtp ==
"el2" || Mtp ==
"tpidr_el2")
316 Features.push_back(
"+tpidr-el2");
317 else if (Mtp ==
"el1" || Mtp ==
"tpidr_el1")
318 Features.push_back(
"+tpidr-el1");
319 else if (Mtp ==
"tpidrro_el0")
320 Features.push_back(
"+tpidrro-el0");
321 else if (Mtp !=
"el0" && Mtp !=
"tpidr_el0")
322 D.
Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
326 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
327 StringRef
Scope = A->getValue();
328 bool EnableRetBr =
false;
329 bool EnableBlr =
false;
330 bool DisableComdat =
false;
331 if (
Scope !=
"none") {
333 Scope.split(Opts,
",");
334 for (
auto Opt : Opts) {
341 if (Opt ==
"retbr") {
349 if (Opt ==
"comdat") {
350 DisableComdat =
false;
353 if (Opt ==
"nocomdat") {
354 DisableComdat =
true;
357 D.
Diag(diag::err_drv_unsupported_option_argument)
358 << A->getSpelling() <<
Scope;
364 Features.push_back(
"+harden-sls-retbr");
366 Features.push_back(
"+harden-sls-blr");
368 Features.push_back(
"+harden-sls-nocomdat");
373 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
374 if (A->getOption().matches(options::OPT_mcrc))
375 Features.push_back(
"+crc");
377 Features.push_back(
"-crc");
382 bool HasNoSM4 =
false;
383 bool HasNoSHA3 =
false;
384 bool HasNoSHA2 =
false;
385 bool HasNoAES =
false;
387 bool HasSHA3 =
false;
388 bool HasSHA2 =
false;
390 bool HasCrypto =
false;
391 bool HasNoCrypto =
false;
392 int FullFP16Pos = -1;
393 int NoFullFP16Pos = -1;
395 int NoFP16FMLPos = -1;
396 int ArchFeatPos = -1;
398 for (
auto I = Features.begin(), E = Features.end(); I != E; I++) {
399 if (*I ==
"+v8a") V8Version = 0;
400 else if (*I ==
"+v8.1a") V8Version = 1;
401 else if (*I ==
"+v8.2a") V8Version = 2;
402 else if (*I ==
"+v8.3a") V8Version = 3;
403 else if (*I ==
"+v8.4a") V8Version = 4;
404 else if (*I ==
"+v8.5a") V8Version = 5;
405 else if (*I ==
"+v8.6a") V8Version = 6;
406 else if (*I ==
"+v8.7a") V8Version = 7;
407 else if (*I ==
"+v8.8a") V8Version = 8;
408 else if (*I ==
"+v8.9a") V8Version = 9;
409 else if (*I ==
"+v9a") V9Version = 0;
410 else if (*I ==
"+v9.1a") V9Version = 1;
411 else if (*I ==
"+v9.2a") V9Version = 2;
412 else if (*I ==
"+v9.3a") V9Version = 3;
413 else if (*I ==
"+v9.4a") V9Version = 4;
414 else if (*I ==
"+v9.5a") V9Version = 5;
415 else if (*I ==
"+sm4") HasSM4 =
true;
416 else if (*I ==
"+sha3") HasSHA3 =
true;
417 else if (*I ==
"+sha2") HasSHA2 =
true;
418 else if (*I ==
"+aes") HasAES =
true;
419 else if (*I ==
"-sm4") HasNoSM4 =
true;
420 else if (*I ==
"-sha3") HasNoSHA3 =
true;
421 else if (*I ==
"-sha2") HasNoSHA2 =
true;
422 else if (*I ==
"-aes") HasNoAES =
true;
423 else if (*I ==
"+fp16fml") FP16FMLPos = I - Features.begin();
424 else if (*I ==
"-fp16fml") NoFP16FMLPos = I - Features.begin();
425 else if (*I ==
"-fullfp16") NoFullFP16Pos = I - Features.begin();
426 else if (*I ==
"+fullfp16") FullFP16Pos = I - Features.begin();
428 else if (*I ==
"+crypto") {
431 }
else if (*I ==
"-crypto" || *I ==
"-neon") {
434 HasSM4 = HasSHA2 = HasSHA3 = HasAES =
false;
437 if (ArchFeatPos == -1 && (V8Version != -1 || V9Version != -1))
438 ArchFeatPos = I - Features.begin();
444 if (V8Version >= 4) {
446 if (FullFP16Pos > NoFullFP16Pos && FullFP16Pos > FP16FMLPos && FullFP16Pos > NoFP16FMLPos)
449 Features.push_back(
"+fp16fml");
451 goto fp16_fml_fallthrough;
457 if (NoFullFP16Pos > FP16FMLPos)
458 Features.push_back(
"-fp16fml");
460 else if (NoFullFP16Pos < FP16FMLPos)
461 Features.push_back(
"+fullfp16");
469 if (V8Version >= 4 || V9Version >= 0) {
470 if (HasCrypto && !HasNoCrypto) {
475 Features.push_back(
"+sm4");
477 Features.push_back(
"+sha3");
479 Features.push_back(
"+sha2");
481 Features.push_back(
"+aes");
482 }
else if (HasNoCrypto) {
487 Features.push_back(
"-sm4");
489 Features.push_back(
"-sha3");
491 Features.push_back(
"-sha2");
493 Features.push_back(
"-aes");
496 if (HasCrypto && !HasNoCrypto) {
498 Features.push_back(
"+sha2");
500 Features.push_back(
"+aes");
501 }
else if (HasNoCrypto) {
503 Features.push_back(
"-sha2");
505 Features.push_back(
"-aes");
506 if (V8Version == 2 || V8Version == 3) {
507 Features.push_back(
"-sm4");
508 Features.push_back(
"-sha3");
513 if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
514 options::OPT_munaligned_access)) {
515 if (A->getOption().matches(options::OPT_mno_unaligned_access))
516 Features.push_back(
"+strict-align");
517 }
else if (Triple.isOSOpenBSD())
518 Features.push_back(
"+strict-align");
520 if (Args.hasArg(options::OPT_ffixed_x1))
521 Features.push_back(
"+reserve-x1");
523 if (Args.hasArg(options::OPT_ffixed_x2))
524 Features.push_back(
"+reserve-x2");
526 if (Args.hasArg(options::OPT_ffixed_x3))
527 Features.push_back(
"+reserve-x3");
529 if (Args.hasArg(options::OPT_ffixed_x4))
530 Features.push_back(
"+reserve-x4");
532 if (Args.hasArg(options::OPT_ffixed_x5))
533 Features.push_back(
"+reserve-x5");
535 if (Args.hasArg(options::OPT_ffixed_x6))
536 Features.push_back(
"+reserve-x6");
538 if (Args.hasArg(options::OPT_ffixed_x7))
539 Features.push_back(
"+reserve-x7");
541 if (Args.hasArg(options::OPT_ffixed_x9))
542 Features.push_back(
"+reserve-x9");
544 if (Args.hasArg(options::OPT_ffixed_x10))
545 Features.push_back(
"+reserve-x10");
547 if (Args.hasArg(options::OPT_ffixed_x11))
548 Features.push_back(
"+reserve-x11");
550 if (Args.hasArg(options::OPT_ffixed_x12))
551 Features.push_back(
"+reserve-x12");
553 if (Args.hasArg(options::OPT_ffixed_x13))
554 Features.push_back(
"+reserve-x13");
556 if (Args.hasArg(options::OPT_ffixed_x14))
557 Features.push_back(
"+reserve-x14");
559 if (Args.hasArg(options::OPT_ffixed_x15))
560 Features.push_back(
"+reserve-x15");
562 if (Args.hasArg(options::OPT_ffixed_x18))
563 Features.push_back(
"+reserve-x18");
565 if (Args.hasArg(options::OPT_ffixed_x20))
566 Features.push_back(
"+reserve-x20");
568 if (Args.hasArg(options::OPT_ffixed_x21))
569 Features.push_back(
"+reserve-x21");
571 if (Args.hasArg(options::OPT_ffixed_x22))
572 Features.push_back(
"+reserve-x22");
574 if (Args.hasArg(options::OPT_ffixed_x23))
575 Features.push_back(
"+reserve-x23");
577 if (Args.hasArg(options::OPT_ffixed_x24))
578 Features.push_back(
"+reserve-x24");
580 if (Args.hasArg(options::OPT_ffixed_x25))
581 Features.push_back(
"+reserve-x25");
583 if (Args.hasArg(options::OPT_ffixed_x26))
584 Features.push_back(
"+reserve-x26");
586 if (Args.hasArg(options::OPT_ffixed_x27))
587 Features.push_back(
"+reserve-x27");
589 if (Args.hasArg(options::OPT_ffixed_x28))
590 Features.push_back(
"+reserve-x28");
592 if (Args.hasArg(options::OPT_ffixed_x30))
593 Features.push_back(
"+reserve-x30");
595 if (Args.hasArg(options::OPT_fcall_saved_x8))
596 Features.push_back(
"+call-saved-x8");
598 if (Args.hasArg(options::OPT_fcall_saved_x9))
599 Features.push_back(
"+call-saved-x9");
601 if (Args.hasArg(options::OPT_fcall_saved_x10))
602 Features.push_back(
"+call-saved-x10");
604 if (Args.hasArg(options::OPT_fcall_saved_x11))
605 Features.push_back(
"+call-saved-x11");
607 if (Args.hasArg(options::OPT_fcall_saved_x12))
608 Features.push_back(
"+call-saved-x12");
610 if (Args.hasArg(options::OPT_fcall_saved_x13))
611 Features.push_back(
"+call-saved-x13");
613 if (Args.hasArg(options::OPT_fcall_saved_x14))
614 Features.push_back(
"+call-saved-x14");
616 if (Args.hasArg(options::OPT_fcall_saved_x15))
617 Features.push_back(
"+call-saved-x15");
619 if (Args.hasArg(options::OPT_fcall_saved_x18))
620 Features.push_back(
"+call-saved-x18");
622 if (Args.hasArg(options::OPT_mno_neg_immediates))
623 Features.push_back(
"+no-neg-immediates");
625 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
626 options::OPT_mno_fix_cortex_a53_835769)) {
627 if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
628 Features.push_back(
"+fix-cortex-a53-835769");
630 Features.push_back(
"-fix-cortex-a53-835769");
631 }
else if (Triple.isAndroid() || Triple.isOHOSFamily()) {
633 Features.push_back(
"+fix-cortex-a53-835769");
634 }
else if (Triple.isOSFuchsia()) {
635 std::string CPU =
getCPUName(D, Args, Triple);
636 if (CPU.empty() || CPU ==
"generic" || CPU ==
"cortex-a53")
637 Features.push_back(
"+fix-cortex-a53-835769");
640 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
641 Features.push_back(
"+no-bti-at-return-twice");
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