13#include "llvm/ADT/StringSwitch.h"
14#include "llvm/Option/ArgList.h"
15#include "llvm/TargetParser/ARMTargetParser.h"
16#include "llvm/TargetParser/Host.h"
25 llvm::StringRef Arch = Triple.getArchName();
26 return llvm::ARM::parseArchVersion(Arch);
31 llvm::StringRef Arch = Triple.getArchName();
32 return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::M;
40 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
41 options::OPT_mbig_endian)) {
42 return !A->getOption().matches(options::OPT_mlittle_endian);
45 return Triple.getArch() == llvm::Triple::armeb ||
46 Triple.getArch() == llvm::Triple::thumbeb;
51 llvm::StringRef Arch = Triple.getArchName();
52 return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A;
57 llvm::StringRef &CPU,
bool FromAs) {
58 if (
const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
60 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
66 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
69 for (StringRef
Value : A->getValues()) {
70 if (
Value.starts_with(
"-mcpu="))
71 CPU =
Value.substr(6);
72 if (
Value.starts_with(
"-march="))
73 Arch =
Value.substr(7);
81 const ArgList &Args, StringRef HWDiv,
82 std::vector<StringRef> &Features) {
83 uint64_t HWDivID = llvm::ARM::parseHWDiv(HWDiv);
84 if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
85 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
90 const ArgList &Args, StringRef FPU,
91 std::vector<StringRef> &Features) {
92 llvm::ARM::FPUKind FPUKind = llvm::ARM::parseFPU(FPU);
93 if (!llvm::ARM::getFPUFeatures(FPUKind, Features))
94 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
100 llvm::ARM::ArchKind ArchKind,
101 std::vector<StringRef> &Features,
102 llvm::ARM::FPUKind &ArgFPUKind) {
104 text.split(
Split, StringRef(
"+"), -1,
false);
106 for (StringRef Feature :
Split) {
107 if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features, ArgFPUKind))
114 std::vector<StringRef> &Features) {
115 CPU = CPU.split(
"+").first;
116 if (CPU !=
"generic") {
117 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
118 uint64_t Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
119 llvm::ARM::getExtensionFeatures(Extension, Features);
127 llvm::StringRef ArchName, llvm::StringRef CPUName,
128 std::vector<StringRef> &Features,
129 const llvm::Triple &Triple,
130 llvm::ARM::FPUKind &ArgFPUKind) {
131 std::pair<StringRef, StringRef>
Split = ArchName.split(
"+");
134 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
135 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
136 (
Split.second.size() &&
139 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
140 << A->getSpelling() << A->getValue();
145 llvm::StringRef CPUName, llvm::StringRef ArchName,
146 std::vector<StringRef> &Features,
147 const llvm::Triple &Triple,
148 llvm::ARM::FPUKind &ArgFPUKind) {
149 std::pair<StringRef, StringRef>
Split = CPUName.split(
"+");
152 llvm::ARM::ArchKind ArchKind =
154 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
156 Features, ArgFPUKind)))
157 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
158 << A->getSpelling() << A->getValue();
168 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
169 options::OPT_mfloat_abi_EQ);
170 if (A && (A->getOption().matches(options::OPT_mhard_float) ||
171 (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
172 A->getValue() == StringRef(
"hard"))))
173 D.
Diag(clang::diag::warn_drv_no_floating_point_registers)
174 << A->getAsString(Args);
180 return T.getEnvironment() == llvm::Triple::EABI ||
181 T.getEnvironment() == llvm::Triple::EABIHF ||
190 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
191 return Triple.isARM() || AK == llvm::ARM::ArchKind::ARMV6T2 ||
192 (Ver >= 7 && AK != llvm::ARM::ArchKind::ARMV8MBaseline);
197 const llvm::Triple &Triple,
bool ForAS) {
198 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
200 llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
201 .Case(
"cp15", ReadTPMode::TPIDRURO)
202 .Case(
"tpidrurw", ReadTPMode::TPIDRURW)
203 .Case(
"tpidruro", ReadTPMode::TPIDRURO)
204 .Case(
"tpidrprw", ReadTPMode::TPIDRPRW)
205 .Case(
"soft", ReadTPMode::Soft)
206 .Default(ReadTPMode::Invalid);
207 if ((ThreadPointer == ReadTPMode::TPIDRURW ||
208 ThreadPointer == ReadTPMode::TPIDRURO ||
209 ThreadPointer == ReadTPMode::TPIDRPRW) &&
210 !isHardTPSupported(Triple) && !ForAS) {
211 D.
Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName();
212 return ReadTPMode::Invalid;
214 if (ThreadPointer != ReadTPMode::Invalid)
215 return ThreadPointer;
216 if (StringRef(A->getValue()).empty())
217 D.
Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
219 D.
Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
220 return ReadTPMode::Invalid;
222 return ReadTPMode::Soft;
226 types::ID InputType, llvm::Triple &Triple) {
227 StringRef MCPU, MArch;
228 if (
const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
229 MCPU = A->getValue();
230 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
231 MArch = A->getValue();
233 std::string CPU = Triple.isOSBinFormatMachO()
238 bool IsBigEndian = Triple.getArch() == llvm::Triple::armeb ||
239 Triple.getArch() == llvm::Triple::thumbeb;
242 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
243 options::OPT_mbig_endian)) {
244 IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
246 std::string ArchName = IsBigEndian ?
"armeb" :
"arm";
250 llvm::ARM::parseArchProfile(Suffix) == llvm::ARM::ProfileKind::M;
251 bool ThumbDefault = IsMProfile ||
253 (llvm::ARM::parseArchVersion(Suffix) == 7 &&
254 Triple.isOSBinFormatMachO()) ||
256 Triple.isOSWindows();
260 bool ARMModeRequested =
261 !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
262 if (IsMProfile && ARMModeRequested) {
264 D.
Diag(diag::err_cpu_unsupported_isa) << CPU <<
"ARM";
266 D.
Diag(diag::err_arch_unsupported_isa)
273 bool IsThumb =
false;
274 if (InputType != types::TY_PP_Asm)
276 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
281 llvm::StringRef WaMArch, WaMCPU;
283 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
284 for (StringRef
Value : A->getValues()) {
286 if (
Value ==
"-mthumb")
288 else if (
Value.starts_with(
"-march="))
289 WaMArch =
Value.substr(7);
290 else if (
Value.starts_with(
"-mcpu="))
291 WaMCPU =
Value.substr(6);
295 if (WaMCPU.size() || WaMArch.size()) {
305 if (IsThumb || IsMProfile || Triple.isOSWindows()) {
307 ArchName =
"thumbeb";
311 Triple.setArchName(ArchName + Suffix.str());
315 llvm::Triple &Triple) {
316 if (Triple.isOSLiteOS()) {
317 Triple.setEnvironment(llvm::Triple::OpenHOS);
324 switch (Triple.getEnvironment()) {
325 case llvm::Triple::GNUEABI:
326 case llvm::Triple::GNUEABIHF:
327 Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHF
328 : llvm::Triple::GNUEABI);
330 case llvm::Triple::EABI:
331 case llvm::Triple::EABIHF:
332 Triple.setEnvironment(isHardFloat ? llvm::Triple::EABIHF
333 : llvm::Triple::EABI);
335 case llvm::Triple::MuslEABI:
336 case llvm::Triple::MuslEABIHF:
337 Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF
338 : llvm::Triple::MuslEABI);
340 case llvm::Triple::OpenHOS:
344 if (DefaultABI != arm::FloatABI::Invalid &&
345 isHardFloat != (DefaultABI == arm::FloatABI::Hard)) {
347 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
348 options::OPT_mfloat_abi_EQ);
349 assert(ABIArg &&
"Non-default float abi expected to be from arg");
350 D.
Diag(diag::err_drv_unsupported_opt_for_target)
351 << ABIArg->getAsString(Args) << Triple.getTriple();
364 switch (Triple.getOS()) {
365 case llvm::Triple::Darwin:
366 case llvm::Triple::MacOSX:
367 case llvm::Triple::IOS:
368 case llvm::Triple::TvOS:
369 case llvm::Triple::DriverKit:
370 case llvm::Triple::XROS:
372 if (Triple.isWatchABI())
373 return FloatABI::Hard;
375 return (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
377 case llvm::Triple::WatchOS:
378 return FloatABI::Hard;
381 case llvm::Triple::Win32:
385 return FloatABI::Soft;
386 return FloatABI::Hard;
388 case llvm::Triple::NetBSD:
389 switch (Triple.getEnvironment()) {
390 case llvm::Triple::EABIHF:
391 case llvm::Triple::GNUEABIHF:
392 return FloatABI::Hard;
394 return FloatABI::Soft;
398 case llvm::Triple::FreeBSD:
399 switch (Triple.getEnvironment()) {
400 case llvm::Triple::GNUEABIHF:
401 return FloatABI::Hard;
404 return FloatABI::Soft;
408 case llvm::Triple::Haiku:
409 case llvm::Triple::OpenBSD:
410 return FloatABI::SoftFP;
413 if (Triple.isOHOSFamily())
414 return FloatABI::Soft;
415 switch (Triple.getEnvironment()) {
416 case llvm::Triple::GNUEABIHF:
417 case llvm::Triple::MuslEABIHF:
418 case llvm::Triple::EABIHF:
419 return FloatABI::Hard;
420 case llvm::Triple::GNUEABI:
421 case llvm::Triple::MuslEABI:
422 case llvm::Triple::EABI:
424 return FloatABI::SoftFP;
425 case llvm::Triple::Android:
426 return (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft;
428 return FloatABI::Invalid;
431 return FloatABI::Invalid;
437 const ArgList &Args) {
440 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
441 options::OPT_mfloat_abi_EQ)) {
442 if (A->getOption().matches(options::OPT_msoft_float)) {
443 ABI = FloatABI::Soft;
444 }
else if (A->getOption().matches(options::OPT_mhard_float)) {
445 ABI = FloatABI::Hard;
447 ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
448 .Case(
"soft", FloatABI::Soft)
449 .Case(
"softfp", FloatABI::SoftFP)
450 .Case(
"hard", FloatABI::Hard)
451 .Default(FloatABI::Invalid);
452 if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
453 D.
Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
454 ABI = FloatABI::Soft;
460 if (ABI == FloatABI::Invalid)
463 if (ABI == FloatABI::Invalid) {
465 if (Triple.isOSBinFormatMachO() &&
466 Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
467 ABI = FloatABI::Hard;
469 ABI = FloatABI::Soft;
471 if (Triple.getOS() != llvm::Triple::UnknownOS ||
472 !Triple.isOSBinFormatMachO())
473 D.
Diag(diag::warn_drv_assuming_mfloat_abi_is) <<
"soft";
476 assert(ABI != FloatABI::Invalid &&
"must select an ABI");
481 auto MVE = llvm::find(llvm::reverse(F),
"+mve");
482 auto NoMVE = llvm::find(llvm::reverse(F),
"-mve");
483 return MVE != F.rend() &&
484 (NoMVE == F.rend() || std::distance(MVE, NoMVE) > 0);
488 const llvm::Triple &Triple,
490 std::vector<StringRef> &Features,
491 bool ForAS,
bool ForMultilib) {
493 Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
495 std::optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv, WaArch;
502 std::vector<StringRef> ExtensionFeatures;
518 if (ABI == arm::FloatABI::Soft)
519 Features.push_back(
"+soft-float");
522 if (ABI != arm::FloatABI::Hard)
523 Features.push_back(
"+soft-float-abi");
528 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
531 for (StringRef
Value : A->getValues()) {
532 if (
Value.starts_with(
"-mfpu=")) {
533 WaFPU = std::make_pair(A,
Value.substr(6));
534 }
else if (
Value.starts_with(
"-mcpu=")) {
535 WaCPU = std::make_pair(A,
Value.substr(6));
536 }
else if (
Value.starts_with(
"-mhwdiv=")) {
537 WaHDiv = std::make_pair(A,
Value.substr(8));
538 }
else if (
Value.starts_with(
"-march=")) {
539 WaArch = std::make_pair(A,
Value.substr(7));
547 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))
548 A->ignoreTargetSpecific();
551 if (
getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRURW)
552 Features.push_back(
"+read-tp-tpidrurw");
553 if (
getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRURO)
554 Features.push_back(
"+read-tp-tpidruro");
555 if (
getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRPRW)
556 Features.push_back(
"+read-tp-tpidrprw");
558 const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
559 const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
562 llvm::ARM::FPUKind ArchArgFPUKind = llvm::ARM::FK_INVALID;
563 llvm::ARM::FPUKind CPUArgFPUKind = llvm::ARM::FK_INVALID;
568 D.
Diag(clang::diag::warn_drv_unused_argument)
569 << CPUArg->getAsString(Args);
570 CPUName = WaCPU->second;
571 CPUArg = WaCPU->first;
573 CPUName = CPUArg->getValue();
578 D.
Diag(clang::diag::warn_drv_unused_argument)
579 << ArchArg->getAsString(Args);
580 ArchName = WaArch->second;
583 ExtensionFeatures, Triple, ArchArgFPUKind);
586 }
else if (ArchArg) {
587 ArchName = ArchArg->getValue();
589 Triple, ArchArgFPUKind);
593 if (CPUName ==
"native") {
594 llvm::StringMap<bool> HostFeatures;
595 if (llvm::sys::getHostCPUFeatures(HostFeatures))
596 for (
auto &F : HostFeatures)
598 Args.MakeArgString((F.second ?
"+" :
"-") + F.first()));
599 }
else if (!CPUName.empty()) {
609 Triple, CPUArgFPUKind);
613 (void)Args.getLastArg(options::OPT_mtune_EQ);
616 llvm::ARM::FPUKind FPUKind = llvm::ARM::FK_INVALID;
617 const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
620 D.
Diag(clang::diag::warn_drv_unused_argument)
621 << FPUArg->getAsString(Args);
626 const char *AndroidFPU =
"neon";
627 FPUKind = llvm::ARM::parseFPU(AndroidFPU);
628 if (!llvm::ARM::getFPUFeatures(FPUKind, Features))
629 D.
Diag(clang::diag::err_drv_clang_unsupported)
630 << std::string(
"-mfpu=") + AndroidFPU;
631 }
else if (ArchArgFPUKind != llvm::ARM::FK_INVALID ||
632 CPUArgFPUKind != llvm::ARM::FK_INVALID) {
634 CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : ArchArgFPUKind;
635 (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
639 llvm::ARM::ArchKind ArchKind =
641 FPUKind = llvm::ARM::getDefaultFPU(CPU, ArchKind);
642 (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
649 Features.insert(std::end(Features),
650 std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
653 const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
656 D.
Diag(clang::diag::warn_drv_unused_argument)
657 << HDivArg->getAsString(Args);
666 const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(),
"-fullfp16");
667 const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(),
"+fp16fml");
668 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
669 const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(),
"+fullfp16");
670 if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
673 if (std::find(Features.rbegin(), ItRFullFP16,
"-fp16fml") == ItRFullFP16)
674 Features.push_back(
"+fp16fml");
677 goto fp16_fml_fallthrough;
683 if (ItRNoFullFP16 < ItRFP16FML)
684 Features.push_back(
"-fp16fml");
685 else if (ItRNoFullFP16 > ItRFP16FML)
686 Features.push_back(
"+fullfp16");
693 bool HasFPRegs =
true;
694 if (ABI == arm::FloatABI::Soft) {
695 llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
699 Features.insert(Features.end(),
700 {
"-dotprod",
"-fp16fml",
"-bf16",
"-mve",
"-mve.fp"});
702 FPUKind = llvm::ARM::FK_NONE;
703 }
else if (FPUKind == llvm::ARM::FK_NONE ||
704 ArchArgFPUKind == llvm::ARM::FK_NONE ||
705 CPUArgFPUKind == llvm::ARM::FK_NONE) {
710 Features.insert(Features.end(),
711 {
"-dotprod",
"-fp16fml",
"-bf16",
"-mve.fp"});
713 FPUKind = llvm::ARM::FK_NONE;
716 Features.emplace_back(
"-fpregs");
719 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
720 if (A->getOption().matches(options::OPT_mcrc))
721 Features.push_back(
"+crc");
723 Features.push_back(
"-crc");
734 bool HasSHA2 =
false;
736 const auto ItCrypto =
737 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
738 return F.contains(
"crypto");
741 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
742 return F.contains(
"crypto") || F.contains(
"sha2");
745 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
746 return F.contains(
"crypto") || F.contains(
"aes");
748 const bool FoundSHA2 = ItSHA2 != Features.rend();
749 const bool FoundAES = ItAES != Features.rend();
751 HasSHA2 = ItSHA2->take_front() ==
"+";
753 HasAES = ItAES->take_front() ==
"+";
754 if (ItCrypto != Features.rend()) {
755 if (HasSHA2 && HasAES)
756 Features.push_back(
"+crypto");
758 Features.push_back(
"-crypto");
760 Features.push_back(
"+sha2");
762 Features.push_back(
"-sha2");
764 Features.push_back(
"+aes");
766 Features.push_back(
"-aes");
769 if (HasSHA2 || HasAES) {
772 llvm::ARM::ProfileKind ArchProfile =
773 llvm::ARM::parseArchProfile(ArchSuffix);
774 if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) &&
775 (ArchProfile == llvm::ARM::ProfileKind::A ||
776 ArchProfile == llvm::ARM::ProfileKind::R))) {
778 D.
Diag(clang::diag::warn_target_unsupported_extension)
780 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
782 D.
Diag(clang::diag::warn_target_unsupported_extension)
784 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
790 if (!Args.hasArg(options::OPT_fno_integrated_as)) {
791 Features.push_back(
"-sha2");
792 Features.push_back(
"-aes");
798 if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) {
799 StringRef FrameChainOption = A->getValue();
800 if (FrameChainOption.starts_with(
"aapcs"))
801 Features.push_back(
"+aapcs-frame-chain");
802 if (FrameChainOption ==
"aapcs+leaf")
803 Features.push_back(
"+aapcs-frame-chain-leaf");
807 if (Args.getLastArg(options::OPT_mcmse))
808 Features.push_back(
"+8msecext");
810 if (Arg *A = Args.getLastArg(options::OPT_mfix_cmse_cve_2021_35465,
811 options::OPT_mno_fix_cmse_cve_2021_35465)) {
812 if (!Args.getLastArg(options::OPT_mcmse))
813 D.
Diag(diag::err_opt_not_valid_without_opt)
814 << A->getOption().getName() <<
"-mcmse";
816 if (A->getOption().matches(options::OPT_mfix_cmse_cve_2021_35465))
817 Features.push_back(
"+fix-cmse-cve-2021-35465");
819 Features.push_back(
"-fix-cmse-cve-2021-35465");
823 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a57_aes_1742098,
824 options::OPT_mno_fix_cortex_a57_aes_1742098)) {
825 if (A->getOption().matches(options::OPT_mfix_cortex_a57_aes_1742098)) {
826 Features.push_back(
"+fix-cortex-a57-aes-1742098");
828 Features.push_back(
"-fix-cortex-a57-aes-1742098");
835 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
836 options::OPT_mno_long_calls)) {
837 if (A->getOption().matches(options::OPT_mlong_calls))
838 Features.push_back(
"+long-calls");
839 }
else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
840 !Triple.isWatchOS() && !Triple.isXROS()) {
841 Features.push_back(
"+long-calls");
848 if (!ForAS && !ForMultilib) {
851 if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
852 if (A->getOption().matches(options::OPT_mexecute_only)) {
854 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2 &&
855 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6M)
856 D.
Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
857 else if (llvm::ARM::parseArch(Triple.getArchName()) == llvm::ARM::ArchKind::ARMV6M) {
858 if (Arg *PIArg = Args.getLastArg(options::OPT_fropi, options::OPT_frwpi,
859 options::OPT_fpic, options::OPT_fpie,
860 options::OPT_fPIC, options::OPT_fPIE))
861 D.
Diag(diag::err_opt_not_valid_with_opt_on_target)
862 << A->getAsString(Args) << PIArg->getAsString(Args) << Triple.getArchName();
863 }
else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
864 D.
Diag(diag::err_opt_not_valid_with_opt)
865 << A->getAsString(Args) << B->getAsString(Args);
866 Features.push_back(
"+execute-only");
871 if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
872 options::OPT_munaligned_access,
873 options::OPT_mstrict_align,
874 options::OPT_mno_strict_align)) {
877 A->getOption().matches(options::OPT_mno_unaligned_access) ||
878 A->getOption().matches(options::OPT_mstrict_align)) {
879 Features.push_back(
"+strict-align");
882 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
883 D.
Diag(diag::err_target_unsupported_unaligned) <<
"v6m";
886 else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
887 D.
Diag(diag::err_target_unsupported_unaligned) <<
"v8m.base";
904 if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
905 if (VersionNum < 6 ||
906 Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
907 Features.push_back(
"+strict-align");
908 }
else if (VersionNum < 7 ||
909 Triple.getSubArch() ==
910 llvm::Triple::SubArchType::ARMSubArch_v6m ||
911 Triple.getSubArch() ==
912 llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) {
913 Features.push_back(
"+strict-align");
920 if (Args.hasArg(options::OPT_ffixed_r9))
921 Features.push_back(
"+reserve-r9");
924 if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
925 Features.push_back(
"+no-movt");
927 if (Args.hasArg(options::OPT_mno_neg_immediates))
928 Features.push_back(
"+no-neg-immediates");
931 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
932 StringRef
Scope = A->getValue();
933 bool EnableRetBr =
false;
934 bool EnableBlr =
false;
935 bool DisableComdat =
false;
936 if (
Scope !=
"none") {
938 Scope.split(Opts,
",");
939 for (
auto Opt : Opts) {
946 if (Opt ==
"retbr") {
954 if (Opt ==
"comdat") {
955 DisableComdat =
false;
958 if (Opt ==
"nocomdat") {
959 DisableComdat =
true;
962 D.
Diag(diag::err_drv_unsupported_option_argument)
963 << A->getSpelling() <<
Scope;
968 if (EnableRetBr || EnableBlr)
970 D.
Diag(diag::err_sls_hardening_arm_not_supported)
971 <<
Scope << A->getAsString(Args);
974 Features.push_back(
"+harden-sls-retbr");
976 Features.push_back(
"+harden-sls-blr");
978 Features.push_back(
"+harden-sls-nocomdat");
982 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
983 Features.push_back(
"+no-bti-at-return-twice");
990std::string
arm::getARMArch(StringRef Arch,
const llvm::Triple &Triple) {
993 MArch = std::string(Arch);
995 MArch = std::string(Triple.getArchName());
996 MArch = StringRef(MArch).split(
"+").first.lower();
999 if (MArch ==
"native") {
1000 std::string CPU = std::string(llvm::sys::getHostCPUName());
1001 if (CPU !=
"generic") {
1009 MArch = std::string(
"arm") + Suffix.str();
1018 std::string MArch =
getARMArch(Arch, Triple);
1026 return llvm::ARM::getARMCPUForArch(Triple, MArch);
1031 const llvm::Triple &Triple) {
1035 std::string MCPU = StringRef(CPU).split(
"+").first.lower();
1037 if (MCPU ==
"native")
1038 return std::string(llvm::sys::getHostCPUName());
1051 const llvm::Triple &Triple) {
1052 llvm::ARM::ArchKind ArchKind;
1053 if (CPU ==
"generic" || CPU.empty()) {
1055 ArchKind = llvm::ARM::parseArch(ARMArch);
1056 if (ArchKind == llvm::ARM::ArchKind::INVALID)
1060 llvm::ARM::parseCPUArch(llvm::ARM::getARMCPUForArch(Triple, ARMArch));
1064 ArchKind = (Arch ==
"armv7k" || Arch ==
"thumbv7k")
1065 ? llvm::ARM::ArchKind::ARMV7K
1066 : llvm::ARM::parseCPUArch(CPU);
1075 const llvm::Triple &Triple) {
1076 llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple);
1077 if (ArchKind == llvm::ARM::ArchKind::INVALID)
1079 return llvm::ARM::getSubArch(ArchKind);
1083 const llvm::Triple &Triple) {
1084 if (Args.hasArg(options::OPT_r))
1090 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
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T