12#include "llvm/ADT/StringSwitch.h"
13#include "llvm/Option/ArgList.h"
14#include "llvm/TargetParser/ARMTargetParser.h"
15#include "llvm/TargetParser/Host.h"
24 llvm::StringRef
Arch = Triple.getArchName();
25 return llvm::ARM::parseArchVersion(
Arch);
30 llvm::StringRef
Arch = Triple.getArchName();
31 return llvm::ARM::parseArchProfile(
Arch) == llvm::ARM::ProfileKind::M;
39 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
40 options::OPT_mbig_endian)) {
41 return !A->getOption().matches(options::OPT_mlittle_endian);
44 return Triple.getArch() == llvm::Triple::armeb ||
45 Triple.getArch() == llvm::Triple::thumbeb;
50 llvm::StringRef
Arch = Triple.getArchName();
51 return llvm::ARM::parseArchProfile(
Arch) == llvm::ARM::ProfileKind::A;
56 auto arch = Triple.getArch();
57 if (arch != llvm::Triple::arm && arch != llvm::Triple::thumb &&
58 arch != llvm::Triple::armeb && arch != llvm::Triple::thumbeb)
61 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
64 if (Triple.getOS() != llvm::Triple::UnknownOS)
67 if (Triple.getEnvironment() != llvm::Triple::EABI &&
68 Triple.getEnvironment() != llvm::Triple::EABIHF)
76 llvm::StringRef &CPU,
bool FromAs) {
77 if (
const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
79 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
85 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
88 for (StringRef
Value : A->getValues()) {
89 if (
Value.starts_with(
"-mcpu="))
90 CPU =
Value.substr(6);
91 if (
Value.starts_with(
"-march="))
100 const ArgList &Args, StringRef HWDiv,
101 std::vector<StringRef> &Features) {
102 uint64_t HWDivID = llvm::ARM::parseHWDiv(HWDiv);
103 if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
104 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
109 const ArgList &Args, StringRef FPU,
110 std::vector<StringRef> &Features) {
111 llvm::ARM::FPUKind FPUKind = llvm::ARM::parseFPU(FPU);
112 if (!llvm::ARM::getFPUFeatures(FPUKind, Features))
113 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
119 llvm::ARM::ArchKind ArchKind,
120 std::vector<StringRef> &Features,
121 llvm::ARM::FPUKind &ArgFPUKind) {
123 text.split(
Split, StringRef(
"+"), -1,
false);
126 if (!appendArchExtFeatures(CPU, ArchKind,
Feature, Features, ArgFPUKind))
133 std::vector<StringRef> &Features) {
134 CPU = CPU.split(
"+").first;
135 if (CPU !=
"generic") {
136 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
137 uint64_t Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
138 llvm::ARM::getExtensionFeatures(Extension, Features);
146 llvm::StringRef ArchName, llvm::StringRef CPUName,
147 std::vector<StringRef> &Features,
148 const llvm::Triple &Triple,
149 llvm::ARM::FPUKind &ArgFPUKind) {
150 std::pair<StringRef, StringRef>
Split = ArchName.split(
"+");
153 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
154 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
155 (
Split.second.size() &&
158 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
159 << A->getSpelling() << A->getValue();
164 llvm::StringRef CPUName, llvm::StringRef ArchName,
165 std::vector<StringRef> &Features,
166 const llvm::Triple &Triple,
167 llvm::ARM::FPUKind &ArgFPUKind) {
168 std::pair<StringRef, StringRef>
Split = CPUName.split(
"+");
171 llvm::ARM::ArchKind ArchKind =
173 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
175 Features, ArgFPUKind)))
176 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
177 << A->getSpelling() << A->getValue();
187 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
188 options::OPT_mfloat_abi_EQ);
189 if (A && (A->getOption().matches(options::OPT_mhard_float) ||
190 (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
191 A->getValue() == StringRef(
"hard"))))
192 D.
Diag(clang::diag::warn_drv_no_floating_point_registers)
193 << A->getAsString(Args);
199 return T.getEnvironment() == llvm::Triple::EABI ||
200 T.getEnvironment() == llvm::Triple::EABIHF ||
212 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
213 return AK == llvm::ARM::ArchKind::ARMV6K ||
214 AK == llvm::ARM::ArchKind::ARMV6KZ ||
221 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
222 return AK == llvm::ARM::ArchKind::ARMV6T2 ||
223 (Ver >= 7 && AK != llvm::ARM::ArchKind::ARMV8MBaseline);
228 const llvm::Triple &Triple,
bool ForAS) {
229 Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ);
230 if (A && A->getValue() != StringRef(
"auto")) {
232 llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
233 .Case(
"cp15", ReadTPMode::TPIDRURO)
234 .Case(
"tpidrurw", ReadTPMode::TPIDRURW)
235 .Case(
"tpidruro", ReadTPMode::TPIDRURO)
236 .Case(
"tpidrprw", ReadTPMode::TPIDRPRW)
237 .Case(
"soft", ReadTPMode::Soft)
238 .Default(ReadTPMode::Invalid);
239 if ((ThreadPointer == ReadTPMode::TPIDRURW ||
240 ThreadPointer == ReadTPMode::TPIDRURO ||
241 ThreadPointer == ReadTPMode::TPIDRPRW) &&
243 D.
Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName();
244 return ReadTPMode::Invalid;
246 if (ThreadPointer != ReadTPMode::Invalid)
247 return ThreadPointer;
248 if (StringRef(A->getValue()).empty())
249 D.
Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
251 D.
Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
252 return ReadTPMode::Invalid;
258 bool autoUseHWTPMode =
260 return autoUseHWTPMode ? ReadTPMode::TPIDRURO : ReadTPMode::Soft;
264 types::ID InputType, llvm::Triple &Triple) {
265 StringRef MCPU, MArch;
266 if (
const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
267 MCPU = A->getValue();
268 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
269 MArch = A->getValue();
271 std::string
CPU = Triple.isOSBinFormatMachO()
276 bool IsBigEndian = Triple.getArch() == llvm::Triple::armeb ||
277 Triple.getArch() == llvm::Triple::thumbeb;
280 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
281 options::OPT_mbig_endian)) {
282 IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
284 std::string ArchName = IsBigEndian ?
"armeb" :
"arm";
288 llvm::ARM::parseArchProfile(Suffix) == llvm::ARM::ProfileKind::M;
289 bool ThumbDefault = IsMProfile ||
291 (llvm::ARM::parseArchVersion(Suffix) == 7 &&
292 Triple.isOSBinFormatMachO()) ||
294 Triple.isOSFuchsia() ||
296 Triple.isOSWindows();
300 bool ARMModeRequested =
301 !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
302 if (IsMProfile && ARMModeRequested) {
304 D.
Diag(diag::err_cpu_unsupported_isa) <<
CPU <<
"ARM";
306 D.
Diag(diag::err_arch_unsupported_isa)
313 bool IsThumb =
false;
314 if (InputType != types::TY_PP_Asm)
316 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
321 llvm::StringRef WaMArch, WaMCPU;
323 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
324 for (StringRef
Value : A->getValues()) {
326 if (
Value ==
"-mthumb")
328 else if (
Value.starts_with(
"-march="))
329 WaMArch =
Value.substr(7);
330 else if (
Value.starts_with(
"-mcpu="))
331 WaMCPU =
Value.substr(6);
335 if (WaMCPU.size() || WaMArch.size()) {
345 if (IsThumb || IsMProfile || Triple.isOSWindows()) {
347 ArchName =
"thumbeb";
351 Triple.setArchName(ArchName + Suffix.str());
355 llvm::Triple &Triple) {
356 if (Triple.isOSLiteOS()) {
357 Triple.setEnvironment(llvm::Triple::OpenHOS);
364 switch (Triple.getEnvironment()) {
365 case llvm::Triple::GNUEABI:
366 case llvm::Triple::GNUEABIHF:
367 Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHF
368 : llvm::Triple::GNUEABI);
370 case llvm::Triple::GNUEABIT64:
371 case llvm::Triple::GNUEABIHFT64:
372 Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHFT64
373 : llvm::Triple::GNUEABIT64);
375 case llvm::Triple::EABI:
376 case llvm::Triple::EABIHF:
377 Triple.setEnvironment(isHardFloat ? llvm::Triple::EABIHF
378 : llvm::Triple::EABI);
380 case llvm::Triple::MuslEABI:
381 case llvm::Triple::MuslEABIHF:
382 Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF
383 : llvm::Triple::MuslEABI);
385 case llvm::Triple::OpenHOS:
392 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
393 options::OPT_mfloat_abi_EQ);
394 assert(ABIArg &&
"Non-default float abi expected to be from arg");
395 D.
Diag(diag::err_drv_unsupported_opt_for_target)
396 << ABIArg->getAsString(Args) << Triple.getTriple();
404 llvm::Triple &Triple) {
405 Arg *A = Args.getLastArg(options::OPT_meabi);
409 StringRef
Value = A->getValue();
410 if (
Value ==
"gnu") {
411 switch (Triple.getEnvironment()) {
412 case llvm::Triple::EABI:
413 Triple.setEnvironment(llvm::Triple::GNUEABI);
415 case llvm::Triple::EABIHF:
416 Triple.setEnvironment(llvm::Triple::GNUEABIHF);
422 switch (Triple.getEnvironment()) {
423 case llvm::Triple::GNUEABI:
424 Triple.setEnvironment(llvm::Triple::EABI);
426 case llvm::Triple::GNUEABIHF:
427 Triple.setEnvironment(llvm::Triple::EABIHF);
441 switch (Triple.getOS()) {
442 case llvm::Triple::Darwin:
443 case llvm::Triple::MacOSX:
444 case llvm::Triple::IOS:
445 case llvm::Triple::TvOS:
446 case llvm::Triple::DriverKit:
447 case llvm::Triple::XROS:
449 if (Triple.isWatchABI())
454 case llvm::Triple::WatchOS:
458 case llvm::Triple::Win32:
465 case llvm::Triple::NetBSD:
466 switch (Triple.getEnvironment()) {
467 case llvm::Triple::EABIHF:
468 case llvm::Triple::GNUEABIHF:
475 case llvm::Triple::FreeBSD:
476 switch (Triple.getEnvironment()) {
477 case llvm::Triple::GNUEABIHF:
485 case llvm::Triple::Haiku:
486 case llvm::Triple::OpenBSD:
489 case llvm::Triple::Fuchsia:
493 if (Triple.isOHOSFamily())
495 switch (Triple.getEnvironment()) {
496 case llvm::Triple::GNUEABIHF:
497 case llvm::Triple::GNUEABIHFT64:
498 case llvm::Triple::MuslEABIHF:
499 case llvm::Triple::EABIHF:
501 case llvm::Triple::Android:
502 case llvm::Triple::GNUEABI:
503 case llvm::Triple::GNUEABIT64:
504 case llvm::Triple::MuslEABI:
505 case llvm::Triple::EABI:
518 const ArgList &Args) {
521 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
522 options::OPT_mfloat_abi_EQ)) {
523 if (A->getOption().matches(options::OPT_msoft_float)) {
524 ABI = FloatABI::Soft;
525 }
else if (A->getOption().matches(options::OPT_mhard_float)) {
526 ABI = FloatABI::Hard;
528 ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
529 .Case(
"soft", FloatABI::Soft)
530 .Case(
"softfp", FloatABI::SoftFP)
531 .Case(
"hard", FloatABI::Hard)
532 .Default(FloatABI::Invalid);
533 if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
534 D.
Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
535 ABI = FloatABI::Soft;
541 if (ABI == FloatABI::Invalid)
544 if (ABI == FloatABI::Invalid) {
546 if (Triple.isOSBinFormatMachO() &&
547 Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
548 ABI = FloatABI::Hard;
550 ABI = FloatABI::Soft;
552 if (((Triple.getOS() != llvm::Triple::UnknownOS) &&
553 !Triple.isOSFirmware()) ||
554 !Triple.isOSBinFormatMachO())
555 D.
Diag(diag::warn_drv_assuming_mfloat_abi_is) <<
"soft";
558 assert(ABI != FloatABI::Invalid &&
"must select an ABI");
563 auto MVE = llvm::find(llvm::reverse(F),
"+mve");
564 auto NoMVE = llvm::find(llvm::reverse(F),
"-mve");
565 return MVE != F.rend() &&
566 (NoMVE == F.rend() || std::distance(
MVE, NoMVE) > 0);
570 const llvm::Triple &Triple,
572 std::vector<StringRef> &Features,
573 bool ForAS,
bool ForMultilib) {
575 Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
577 std::optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv, WaArch;
584 std::vector<StringRef> ExtensionFeatures;
601 Features.push_back(
"+soft-float");
605 Features.push_back(
"+soft-float-abi");
610 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
613 for (StringRef
Value : A->getValues()) {
614 if (
Value.starts_with(
"-mfpu=")) {
615 WaFPU = std::make_pair(A,
Value.substr(6));
616 }
else if (
Value.starts_with(
"-mcpu=")) {
617 WaCPU = std::make_pair(A,
Value.substr(6));
618 }
else if (
Value.starts_with(
"-mhwdiv=")) {
619 WaHDiv = std::make_pair(A,
Value.substr(8));
620 }
else if (
Value.starts_with(
"-march=")) {
621 WaArch = std::make_pair(A,
Value.substr(7));
629 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))
630 A->ignoreTargetSpecific();
635 if (TPMode == ReadTPMode::TPIDRURW)
636 Features.push_back(
"+read-tp-tpidrurw");
637 else if (TPMode == ReadTPMode::TPIDRPRW)
638 Features.push_back(
"+read-tp-tpidrprw");
639 else if (TPMode == ReadTPMode::TPIDRURO)
640 Features.push_back(
"+read-tp-tpidruro");
642 const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
643 const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
646 llvm::ARM::FPUKind ArchArgFPUKind = llvm::ARM::FK_INVALID;
647 llvm::ARM::FPUKind CPUArgFPUKind = llvm::ARM::FK_INVALID;
652 D.
Diag(clang::diag::warn_drv_unused_argument)
653 << CPUArg->getAsString(Args);
654 CPUName = WaCPU->second;
655 CPUArg = WaCPU->first;
657 CPUName = CPUArg->getValue();
662 D.
Diag(clang::diag::warn_drv_unused_argument)
663 << ArchArg->getAsString(Args);
664 ArchName = WaArch->second;
667 ExtensionFeatures, Triple, ArchArgFPUKind);
670 }
else if (ArchArg) {
671 ArchName = ArchArg->getValue();
673 Triple, ArchArgFPUKind);
677 if (CPUName ==
"native") {
678 for (
auto &F : llvm::sys::getHostCPUFeatures())
680 Args.MakeArgString((F.second ?
"+" :
"-") + F.first()));
681 }
else if (!CPUName.empty()) {
691 Triple, CPUArgFPUKind);
695 (void)Args.getLastArg(options::OPT_mtune_EQ);
698 llvm::ARM::FPUKind FPUKind = llvm::ARM::FK_INVALID;
699 const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
702 D.
Diag(clang::diag::warn_drv_unused_argument)
703 << FPUArg->getAsString(Args);
708 const char *AndroidFPU =
"neon";
709 FPUKind = llvm::ARM::parseFPU(AndroidFPU);
710 if (!llvm::ARM::getFPUFeatures(FPUKind, Features))
711 D.
Diag(clang::diag::err_drv_clang_unsupported)
712 << std::string(
"-mfpu=") + AndroidFPU;
713 }
else if (ArchArgFPUKind != llvm::ARM::FK_INVALID ||
714 CPUArgFPUKind != llvm::ARM::FK_INVALID) {
716 CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : ArchArgFPUKind;
717 (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
721 if (
Generic && (Triple.isOSWindows() || Triple.isOSDarwin()) &&
723 FPUKind = llvm::ARM::parseFPU(
"neon");
725 llvm::ARM::ArchKind ArchKind =
727 FPUKind = llvm::ARM::getDefaultFPU(CPU, ArchKind);
729 (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
735 Features.insert(std::end(Features),
736 std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
739 const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
742 D.
Diag(clang::diag::warn_drv_unused_argument)
743 << HDivArg->getAsString(Args);
752 const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(),
"-fullfp16");
753 const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(),
"+fp16fml");
754 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
755 const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(),
"+fullfp16");
756 if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
759 if (std::find(Features.rbegin(), ItRFullFP16,
"-fp16fml") == ItRFullFP16)
760 Features.push_back(
"+fp16fml");
763 goto fp16_fml_fallthrough;
769 if (ItRNoFullFP16 < ItRFP16FML)
770 Features.push_back(
"-fp16fml");
771 else if (ItRNoFullFP16 > ItRFP16FML)
772 Features.push_back(
"+fullfp16");
779 bool HasFPRegs =
true;
781 llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
785 Features.insert(Features.end(),
786 {
"-dotprod",
"-fp16fml",
"-bf16",
"-mve",
"-mve.fp"});
788 FPUKind = llvm::ARM::FK_NONE;
789 }
else if (FPUKind == llvm::ARM::FK_NONE ||
790 ArchArgFPUKind == llvm::ARM::FK_NONE ||
791 CPUArgFPUKind == llvm::ARM::FK_NONE) {
796 Features.insert(Features.end(),
797 {
"-dotprod",
"-fp16fml",
"-bf16",
"-mve.fp"});
799 FPUKind = llvm::ARM::FK_NONE;
802 Features.emplace_back(
"-fpregs");
805 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
806 if (A->getOption().matches(options::OPT_mcrc))
807 Features.push_back(
"+crc");
809 Features.push_back(
"-crc");
818 if (FPUKind == llvm::ARM::FK_FPV5_D16 || FPUKind == llvm::ARM::FK_FPV5_SP_D16)
819 Features.push_back(
"-mve.fp");
823 bool HasSimd =
false;
825 llvm::find_if(llvm::reverse(Features),
826 [](
const StringRef F) {
return F.contains(
"neon"); });
827 const bool FPUSupportsNeon = (llvm::ARM::FPUNames[FPUKind].NeonSupport ==
828 llvm::ARM::NeonSupportLevel::Neon) ||
829 (llvm::ARM::FPUNames[FPUKind].NeonSupport ==
830 llvm::ARM::NeonSupportLevel::Crypto);
831 if (ItSimd != Features.rend())
832 HasSimd = ItSimd->starts_with(
"+");
833 if (!HasSimd && FPUSupportsNeon)
834 Features.insert(Features.end(),
835 {
"-sha2",
"-aes",
"-crypto",
"-dotprod",
"-bf16",
"-i8mm"});
845 bool HasSHA2 =
false;
847 bool HasBF16 =
false;
848 bool HasDotprod =
false;
849 bool HasI8MM =
false;
850 const auto ItCrypto =
851 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
852 return F.contains(
"crypto");
855 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
856 return F.contains(
"crypto") || F.contains(
"sha2");
859 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
860 return F.contains(
"crypto") || F.contains(
"aes");
863 llvm::find_if(llvm::reverse(Features),
864 [](
const StringRef F) {
return F.contains(
"bf16"); });
865 const auto ItDotprod =
866 llvm::find_if(llvm::reverse(Features),
867 [](
const StringRef F) {
return F.contains(
"dotprod"); });
869 llvm::find_if(llvm::reverse(Features),
870 [](
const StringRef F) {
return F.contains(
"i8mm"); });
871 if (ItSHA2 != Features.rend())
872 HasSHA2 = ItSHA2->starts_with(
"+");
873 if (ItAES != Features.rend())
874 HasAES = ItAES->starts_with(
"+");
875 if (ItBF16 != Features.rend())
876 HasBF16 = ItBF16->starts_with(
"+");
877 if (ItDotprod != Features.rend())
878 HasDotprod = ItDotprod->starts_with(
"+");
879 if (ItI8MM != Features.rend())
880 HasI8MM = ItI8MM->starts_with(
"+");
881 if (ItCrypto != Features.rend()) {
882 if (HasSHA2 && HasAES)
883 Features.push_back(
"+crypto");
885 Features.push_back(
"-crypto");
887 Features.push_back(
"+sha2");
889 Features.push_back(
"-sha2");
891 Features.push_back(
"+aes");
893 Features.push_back(
"-aes");
896 if (HasAES || HasSHA2 || HasBF16 || HasDotprod || HasI8MM)
897 Features.push_back(
"+neon");
899 if (HasSHA2 || HasAES) {
902 llvm::ARM::ProfileKind ArchProfile =
903 llvm::ARM::parseArchProfile(ArchSuffix);
904 if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) &&
905 (ArchProfile == llvm::ARM::ProfileKind::A ||
906 ArchProfile == llvm::ARM::ProfileKind::R))) {
908 D.
Diag(clang::diag::warn_target_unsupported_extension)
910 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
912 D.
Diag(clang::diag::warn_target_unsupported_extension)
914 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
920 if (!Args.hasArg(options::OPT_fno_integrated_as)) {
921 Features.push_back(
"-sha2");
922 Features.push_back(
"-aes");
928 if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) {
929 StringRef FrameChainOption = A->getValue();
930 if (FrameChainOption.starts_with(
"aapcs"))
931 Features.push_back(
"+aapcs-frame-chain");
935 if (Args.getLastArg(options::OPT_mcmse))
936 Features.push_back(
"+8msecext");
938 if (Arg *A = Args.getLastArg(options::OPT_mfix_cmse_cve_2021_35465,
939 options::OPT_mno_fix_cmse_cve_2021_35465)) {
940 if (!Args.getLastArg(options::OPT_mcmse))
941 D.
Diag(diag::err_opt_not_valid_without_opt)
942 << A->getOption().getName() <<
"-mcmse";
944 if (A->getOption().matches(options::OPT_mfix_cmse_cve_2021_35465))
945 Features.push_back(
"+fix-cmse-cve-2021-35465");
947 Features.push_back(
"-fix-cmse-cve-2021-35465");
951 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a57_aes_1742098,
952 options::OPT_mno_fix_cortex_a57_aes_1742098)) {
953 if (A->getOption().matches(options::OPT_mfix_cortex_a57_aes_1742098)) {
954 Features.push_back(
"+fix-cortex-a57-aes-1742098");
956 Features.push_back(
"-fix-cortex-a57-aes-1742098");
963 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
964 options::OPT_mno_long_calls)) {
965 if (A->getOption().matches(options::OPT_mlong_calls))
966 Features.push_back(
"+long-calls");
967 }
else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
968 !Triple.isWatchOS() && !Triple.isXROS()) {
969 Features.push_back(
"+long-calls");
976 if (!ForAS && !ForMultilib) {
979 if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
980 if (A->getOption().matches(options::OPT_mexecute_only)) {
982 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2 &&
983 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6M)
984 D.
Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
985 else if (llvm::ARM::parseArch(Triple.getArchName()) == llvm::ARM::ArchKind::ARMV6M) {
986 if (Arg *PIArg = Args.getLastArg(options::OPT_fropi, options::OPT_frwpi,
987 options::OPT_fpic, options::OPT_fpie,
988 options::OPT_fPIC, options::OPT_fPIE))
989 D.
Diag(diag::err_opt_not_valid_with_opt_on_target)
990 << A->getAsString(Args) << PIArg->getAsString(Args) << Triple.getArchName();
991 }
else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
992 D.
Diag(diag::err_opt_not_valid_with_opt)
993 << A->getAsString(Args) << B->getAsString(Args);
994 Features.push_back(
"+execute-only");
999 if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
1000 options::OPT_munaligned_access,
1001 options::OPT_mstrict_align,
1002 options::OPT_mno_strict_align)) {
1005 A->getOption().matches(options::OPT_mno_unaligned_access) ||
1006 A->getOption().matches(options::OPT_mstrict_align)) {
1007 Features.push_back(
"+strict-align");
1010 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
1011 D.
Diag(diag::err_target_unsupported_unaligned) <<
"v6m";
1014 else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
1015 D.
Diag(diag::err_target_unsupported_unaligned) <<
"v8m.base";
1032 if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
1033 if (VersionNum < 6 ||
1034 Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
1035 Features.push_back(
"+strict-align");
1036 }
else if (Triple.getVendor() == llvm::Triple::Apple &&
1037 Triple.isOSBinFormatMachO()) {
1039 Features.push_back(
"+strict-align");
1040 }
else if (VersionNum < 7 ||
1041 Triple.getSubArch() ==
1042 llvm::Triple::SubArchType::ARMSubArch_v6m ||
1043 Triple.getSubArch() ==
1044 llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) {
1045 Features.push_back(
"+strict-align");
1052 if (Args.hasArg(options::OPT_ffixed_r9))
1053 Features.push_back(
"+reserve-r9");
1056 if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
1057 Features.push_back(
"+no-movt");
1059 if (Args.hasArg(options::OPT_mno_neg_immediates))
1060 Features.push_back(
"+no-neg-immediates");
1063 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
1064 StringRef
Scope = A->getValue();
1065 bool EnableRetBr =
false;
1066 bool EnableBlr =
false;
1067 bool DisableComdat =
false;
1068 if (
Scope !=
"none") {
1070 Scope.split(Opts,
",");
1071 for (
auto Opt : Opts) {
1078 if (Opt ==
"retbr") {
1086 if (Opt ==
"comdat") {
1087 DisableComdat =
false;
1090 if (Opt ==
"nocomdat") {
1091 DisableComdat =
true;
1094 D.
Diag(diag::err_drv_unsupported_option_argument)
1095 << A->getSpelling() <<
Scope;
1100 if (EnableRetBr || EnableBlr)
1102 D.
Diag(diag::err_sls_hardening_arm_not_supported)
1103 <<
Scope << A->getAsString(Args);
1106 Features.push_back(
"+harden-sls-retbr");
1108 Features.push_back(
"+harden-sls-blr");
1109 if (DisableComdat) {
1110 Features.push_back(
"+harden-sls-nocomdat");
1114 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
1115 Features.push_back(
"+no-bti-at-return-twice");
1125 MArch = std::string(
Arch);
1127 MArch = std::string(Triple.getArchName());
1128 MArch = StringRef(MArch).split(
"+").first.lower();
1131 if (MArch ==
"native") {
1132 std::string
CPU = std::string(llvm::sys::getHostCPUName());
1133 if (CPU !=
"generic") {
1141 MArch = std::string(
"arm") + Suffix.str();
1158 return llvm::ARM::getARMCPUForArch(Triple, MArch);
1163 const llvm::Triple &Triple) {
1167 std::string MCPU = StringRef(CPU).split(
"+").first.lower();
1169 if (MCPU ==
"native")
1170 return std::string(llvm::sys::getHostCPUName());
1183 const llvm::Triple &Triple) {
1184 llvm::ARM::ArchKind ArchKind;
1185 if (CPU ==
"generic" || CPU.empty()) {
1187 ArchKind = llvm::ARM::parseArch(ARMArch);
1188 if (ArchKind == llvm::ARM::ArchKind::INVALID)
1192 llvm::ARM::parseCPUArch(llvm::ARM::getARMCPUForArch(Triple, ARMArch));
1196 ArchKind = (
Arch ==
"armv7k" ||
Arch ==
"thumbv7k")
1197 ? llvm::ARM::ArchKind::ARMV7K
1198 : llvm::ARM::parseCPUArch(CPU);
1207 const llvm::Triple &Triple) {
1208 llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU,
Arch, Triple);
1209 if (ArchKind == llvm::ARM::ArchKind::INVALID)
1211 return llvm::ARM::getSubArch(ArchKind);
1215 const llvm::Triple &Triple) {
1216 if (Args.hasArg(options::OPT_r))
1222 CmdArgs.push_back(
"--be8");
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
Top level wrappers for InstallAPI frontend operations.
const FunctionProtoType * T
@ Generic
not a target-specific vector type