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 auto arch = Triple.getArch();
58 if (
arch != llvm::Triple::arm &&
arch != llvm::Triple::thumb &&
59 arch != llvm::Triple::armeb &&
arch != llvm::Triple::thumbeb)
62 if (Triple.getVendor() != llvm::Triple::UnknownVendor)
65 if (Triple.getOS() != llvm::Triple::UnknownOS)
68 if (Triple.getEnvironment() != llvm::Triple::EABI &&
69 Triple.getEnvironment() != llvm::Triple::EABIHF)
77 llvm::StringRef &CPU,
bool FromAs) {
78 if (
const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
80 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
86 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
89 for (StringRef
Value : A->getValues()) {
90 if (
Value.starts_with(
"-mcpu="))
91 CPU =
Value.substr(6);
92 if (
Value.starts_with(
"-march="))
93 Arch =
Value.substr(7);
101 const ArgList &Args, StringRef HWDiv,
102 std::vector<StringRef> &Features) {
103 uint64_t HWDivID = llvm::ARM::parseHWDiv(HWDiv);
104 if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
105 D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
110 const ArgList &Args, StringRef FPU,
111 std::vector<StringRef> &Features) {
112 llvm::ARM::FPUKind FPUKind = llvm::ARM::parseFPU(FPU);
113 if (!llvm::ARM::getFPUFeatures(FPUKind, Features))
114 D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
120 llvm::ARM::ArchKind ArchKind,
121 std::vector<StringRef> &Features,
122 llvm::ARM::FPUKind &ArgFPUKind) {
124 text.split(
Split, StringRef(
"+"), -1,
false);
126 for (StringRef Feature :
Split) {
127 if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features, ArgFPUKind))
134 std::vector<StringRef> &Features) {
135 CPU = CPU.split(
"+").first;
136 if (CPU !=
"generic") {
137 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
138 uint64_t Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
139 llvm::ARM::getExtensionFeatures(Extension, Features);
147 llvm::StringRef ArchName, llvm::StringRef CPUName,
148 std::vector<StringRef> &Features,
149 const llvm::Triple &Triple,
150 llvm::ARM::FPUKind &ArgFPUKind) {
151 std::pair<StringRef, StringRef>
Split = ArchName.split(
"+");
154 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
155 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
156 (
Split.second.size() &&
159 D.Diag(clang::diag::err_drv_unsupported_option_argument)
160 << A->getSpelling() << A->getValue();
165 llvm::StringRef CPUName, llvm::StringRef ArchName,
166 std::vector<StringRef> &Features,
167 const llvm::Triple &Triple,
168 llvm::ARM::FPUKind &ArgFPUKind) {
169 std::pair<StringRef, StringRef>
Split = CPUName.split(
"+");
172 llvm::ARM::ArchKind ArchKind =
174 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
176 Features, ArgFPUKind)))
177 D.Diag(clang::diag::err_drv_unsupported_option_argument)
178 << A->getSpelling() << A->getValue();
188 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
189 options::OPT_mfloat_abi_EQ);
190 if (A && (A->getOption().matches(options::OPT_mhard_float) ||
191 (A->getOption().matches(options::OPT_mfloat_abi_EQ) &&
192 A->getValue() == StringRef(
"hard"))))
193 D.Diag(clang::diag::warn_drv_no_floating_point_registers)
194 << A->getAsString(Args);
200 return T.getEnvironment() == llvm::Triple::EABI ||
201 T.getEnvironment() == llvm::Triple::EABIHF ||
210 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(Triple.getArchName());
211 return Triple.isARM() || AK == llvm::ARM::ArchKind::ARMV6T2 ||
212 (Ver >= 7 && AK != llvm::ARM::ArchKind::ARMV8MBaseline);
217 const llvm::Triple &Triple,
bool ForAS) {
218 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
220 llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
221 .Case(
"cp15", ReadTPMode::TPIDRURO)
222 .Case(
"tpidrurw", ReadTPMode::TPIDRURW)
223 .Case(
"tpidruro", ReadTPMode::TPIDRURO)
224 .Case(
"tpidrprw", ReadTPMode::TPIDRPRW)
225 .Case(
"soft", ReadTPMode::Soft)
226 .Default(ReadTPMode::Invalid);
227 if ((ThreadPointer == ReadTPMode::TPIDRURW ||
228 ThreadPointer == ReadTPMode::TPIDRURO ||
229 ThreadPointer == ReadTPMode::TPIDRPRW) &&
230 !isHardTPSupported(Triple) && !ForAS) {
231 D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName();
232 return ReadTPMode::Invalid;
234 if (ThreadPointer != ReadTPMode::Invalid)
235 return ThreadPointer;
236 if (StringRef(A->getValue()).empty())
237 D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
239 D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
240 return ReadTPMode::Invalid;
242 return ReadTPMode::Soft;
246 types::ID InputType, llvm::Triple &Triple) {
247 StringRef MCPU, MArch;
248 if (
const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
249 MCPU = A->getValue();
250 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
251 MArch = A->getValue();
253 std::string CPU = Triple.isOSBinFormatMachO()
258 bool IsBigEndian = Triple.getArch() == llvm::Triple::armeb ||
259 Triple.getArch() == llvm::Triple::thumbeb;
262 if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
263 options::OPT_mbig_endian)) {
264 IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
266 std::string ArchName = IsBigEndian ?
"armeb" :
"arm";
270 llvm::ARM::parseArchProfile(Suffix) == llvm::ARM::ProfileKind::M;
271 bool ThumbDefault = IsMProfile ||
273 (llvm::ARM::parseArchVersion(Suffix) == 7 &&
274 Triple.isOSBinFormatMachO()) ||
276 Triple.isOSWindows();
280 bool ARMModeRequested =
281 !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
282 if (IsMProfile && ARMModeRequested) {
284 D.Diag(diag::err_cpu_unsupported_isa) << CPU <<
"ARM";
286 D.Diag(diag::err_arch_unsupported_isa)
293 bool IsThumb =
false;
294 if (InputType != types::TY_PP_Asm)
296 Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
301 llvm::StringRef WaMArch, WaMCPU;
303 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
304 for (StringRef
Value : A->getValues()) {
306 if (
Value ==
"-mthumb")
308 else if (
Value.starts_with(
"-march="))
309 WaMArch =
Value.substr(7);
310 else if (
Value.starts_with(
"-mcpu="))
311 WaMCPU =
Value.substr(6);
315 if (WaMCPU.size() || WaMArch.size()) {
325 if (IsThumb || IsMProfile || Triple.isOSWindows()) {
327 ArchName =
"thumbeb";
331 Triple.setArchName(ArchName + Suffix.str());
335 llvm::Triple &Triple) {
336 if (Triple.isOSLiteOS()) {
337 Triple.setEnvironment(llvm::Triple::OpenHOS);
344 switch (Triple.getEnvironment()) {
345 case llvm::Triple::GNUEABI:
346 case llvm::Triple::GNUEABIHF:
347 Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHF
348 : llvm::Triple::GNUEABI);
350 case llvm::Triple::GNUEABIT64:
351 case llvm::Triple::GNUEABIHFT64:
352 Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHFT64
353 : llvm::Triple::GNUEABIT64);
355 case llvm::Triple::EABI:
356 case llvm::Triple::EABIHF:
357 Triple.setEnvironment(isHardFloat ? llvm::Triple::EABIHF
358 : llvm::Triple::EABI);
360 case llvm::Triple::MuslEABI:
361 case llvm::Triple::MuslEABIHF:
362 Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF
363 : llvm::Triple::MuslEABI);
365 case llvm::Triple::OpenHOS:
369 if (DefaultABI != arm::FloatABI::Invalid &&
370 isHardFloat != (DefaultABI == arm::FloatABI::Hard)) {
372 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
373 options::OPT_mfloat_abi_EQ);
374 assert(ABIArg &&
"Non-default float abi expected to be from arg");
375 D.Diag(diag::err_drv_unsupported_opt_for_target)
376 << ABIArg->getAsString(Args) << Triple.getTriple();
389 switch (Triple.getOS()) {
390 case llvm::Triple::Darwin:
391 case llvm::Triple::MacOSX:
392 case llvm::Triple::IOS:
393 case llvm::Triple::TvOS:
394 case llvm::Triple::DriverKit:
395 case llvm::Triple::XROS:
397 if (Triple.isWatchABI())
398 return FloatABI::Hard;
400 return (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
402 case llvm::Triple::WatchOS:
403 return FloatABI::Hard;
406 case llvm::Triple::Win32:
410 return FloatABI::Soft;
411 return FloatABI::Hard;
413 case llvm::Triple::NetBSD:
414 switch (Triple.getEnvironment()) {
415 case llvm::Triple::EABIHF:
416 case llvm::Triple::GNUEABIHF:
417 return FloatABI::Hard;
419 return FloatABI::Soft;
423 case llvm::Triple::FreeBSD:
424 switch (Triple.getEnvironment()) {
425 case llvm::Triple::GNUEABIHF:
426 return FloatABI::Hard;
429 return FloatABI::Soft;
433 case llvm::Triple::Haiku:
434 case llvm::Triple::OpenBSD:
435 return FloatABI::SoftFP;
438 if (Triple.isOHOSFamily())
439 return FloatABI::Soft;
440 switch (Triple.getEnvironment()) {
441 case llvm::Triple::GNUEABIHF:
442 case llvm::Triple::GNUEABIHFT64:
443 case llvm::Triple::MuslEABIHF:
444 case llvm::Triple::EABIHF:
445 return FloatABI::Hard;
446 case llvm::Triple::GNUEABI:
447 case llvm::Triple::GNUEABIT64:
448 case llvm::Triple::MuslEABI:
449 case llvm::Triple::EABI:
451 return FloatABI::SoftFP;
452 case llvm::Triple::Android:
453 return (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft;
455 return FloatABI::Invalid;
458 return FloatABI::Invalid;
464 const ArgList &Args) {
467 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
468 options::OPT_mfloat_abi_EQ)) {
469 if (A->getOption().matches(options::OPT_msoft_float)) {
470 ABI = FloatABI::Soft;
471 }
else if (A->getOption().matches(options::OPT_mhard_float)) {
472 ABI = FloatABI::Hard;
474 ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
475 .Case(
"soft", FloatABI::Soft)
476 .Case(
"softfp", FloatABI::SoftFP)
477 .Case(
"hard", FloatABI::Hard)
478 .Default(FloatABI::Invalid);
479 if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
480 D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
481 ABI = FloatABI::Soft;
487 if (ABI == FloatABI::Invalid)
490 if (ABI == FloatABI::Invalid) {
492 if (Triple.isOSBinFormatMachO() &&
493 Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
494 ABI = FloatABI::Hard;
496 ABI = FloatABI::Soft;
498 if (Triple.getOS() != llvm::Triple::UnknownOS ||
499 !Triple.isOSBinFormatMachO())
500 D.Diag(diag::warn_drv_assuming_mfloat_abi_is) <<
"soft";
503 assert(ABI != FloatABI::Invalid &&
"must select an ABI");
508 auto MVE = llvm::find(llvm::reverse(F),
"+mve");
509 auto NoMVE = llvm::find(llvm::reverse(F),
"-mve");
510 return MVE != F.rend() &&
511 (NoMVE == F.rend() || std::distance(MVE, NoMVE) > 0);
515 const llvm::Triple &Triple,
517 std::vector<StringRef> &Features,
518 bool ForAS,
bool ForMultilib) {
520 Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
522 std::optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv, WaArch;
529 std::vector<StringRef> ExtensionFeatures;
545 if (ABI == arm::FloatABI::Soft)
546 Features.push_back(
"+soft-float");
549 if (ABI != arm::FloatABI::Hard)
550 Features.push_back(
"+soft-float-abi");
555 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
558 for (StringRef
Value : A->getValues()) {
559 if (
Value.starts_with(
"-mfpu=")) {
560 WaFPU = std::make_pair(A,
Value.substr(6));
561 }
else if (
Value.starts_with(
"-mcpu=")) {
562 WaCPU = std::make_pair(A,
Value.substr(6));
563 }
else if (
Value.starts_with(
"-mhwdiv=")) {
564 WaHDiv = std::make_pair(A,
Value.substr(8));
565 }
else if (
Value.starts_with(
"-march=")) {
566 WaArch = std::make_pair(A,
Value.substr(7));
574 if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))
575 A->ignoreTargetSpecific();
578 if (
getReadTPMode(
D, Args, Triple, ForAS) == ReadTPMode::TPIDRURW)
579 Features.push_back(
"+read-tp-tpidrurw");
580 if (
getReadTPMode(
D, Args, Triple, ForAS) == ReadTPMode::TPIDRURO)
581 Features.push_back(
"+read-tp-tpidruro");
582 if (
getReadTPMode(
D, Args, Triple, ForAS) == ReadTPMode::TPIDRPRW)
583 Features.push_back(
"+read-tp-tpidrprw");
585 const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
586 const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
589 llvm::ARM::FPUKind ArchArgFPUKind = llvm::ARM::FK_INVALID;
590 llvm::ARM::FPUKind CPUArgFPUKind = llvm::ARM::FK_INVALID;
595 D.Diag(clang::diag::warn_drv_unused_argument)
596 << CPUArg->getAsString(Args);
597 CPUName = WaCPU->second;
598 CPUArg = WaCPU->first;
600 CPUName = CPUArg->getValue();
605 D.Diag(clang::diag::warn_drv_unused_argument)
606 << ArchArg->getAsString(Args);
607 ArchName = WaArch->second;
610 ExtensionFeatures, Triple, ArchArgFPUKind);
613 }
else if (ArchArg) {
614 ArchName = ArchArg->getValue();
616 Triple, ArchArgFPUKind);
620 if (CPUName ==
"native") {
621 for (
auto &F : llvm::sys::getHostCPUFeatures())
623 Args.MakeArgString((F.second ?
"+" :
"-") + F.first()));
624 }
else if (!CPUName.empty()) {
634 Triple, CPUArgFPUKind);
638 (void)Args.getLastArg(options::OPT_mtune_EQ);
641 llvm::ARM::FPUKind FPUKind = llvm::ARM::FK_INVALID;
642 const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
645 D.Diag(clang::diag::warn_drv_unused_argument)
646 << FPUArg->getAsString(Args);
651 const char *AndroidFPU =
"neon";
652 FPUKind = llvm::ARM::parseFPU(AndroidFPU);
653 if (!llvm::ARM::getFPUFeatures(FPUKind, Features))
654 D.Diag(clang::diag::err_drv_clang_unsupported)
655 << std::string(
"-mfpu=") + AndroidFPU;
656 }
else if (ArchArgFPUKind != llvm::ARM::FK_INVALID ||
657 CPUArgFPUKind != llvm::ARM::FK_INVALID) {
659 CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : ArchArgFPUKind;
660 (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
665 if (CPU !=
"generic")
667 llvm::ARM::ArchKind ArchKind =
669 FPUKind = llvm::ARM::getDefaultFPU(CPU, ArchKind);
670 (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
672 if (
Generic && (Triple.isOSWindows() || Triple.isOSDarwin()) &&
674 FPUKind = llvm::ARM::parseFPU(
"neon");
675 (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
682 Features.insert(std::end(Features),
683 std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
686 const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
689 D.Diag(clang::diag::warn_drv_unused_argument)
690 << HDivArg->getAsString(Args);
699 const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(),
"-fullfp16");
700 const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(),
"+fp16fml");
701 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
702 const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(),
"+fullfp16");
703 if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
706 if (std::find(Features.rbegin(), ItRFullFP16,
"-fp16fml") == ItRFullFP16)
707 Features.push_back(
"+fp16fml");
710 goto fp16_fml_fallthrough;
716 if (ItRNoFullFP16 < ItRFP16FML)
717 Features.push_back(
"-fp16fml");
718 else if (ItRNoFullFP16 > ItRFP16FML)
719 Features.push_back(
"+fullfp16");
726 bool HasFPRegs =
true;
727 if (ABI == arm::FloatABI::Soft) {
728 llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
732 Features.insert(Features.end(),
733 {
"-dotprod",
"-fp16fml",
"-bf16",
"-mve",
"-mve.fp"});
735 FPUKind = llvm::ARM::FK_NONE;
736 }
else if (FPUKind == llvm::ARM::FK_NONE ||
737 ArchArgFPUKind == llvm::ARM::FK_NONE ||
738 CPUArgFPUKind == llvm::ARM::FK_NONE) {
743 Features.insert(Features.end(),
744 {
"-dotprod",
"-fp16fml",
"-bf16",
"-mve.fp"});
746 FPUKind = llvm::ARM::FK_NONE;
749 Features.emplace_back(
"-fpregs");
752 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
753 if (A->getOption().matches(options::OPT_mcrc))
754 Features.push_back(
"+crc");
756 Features.push_back(
"-crc");
767 bool HasSHA2 =
false;
769 const auto ItCrypto =
770 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
771 return F.contains(
"crypto");
774 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
775 return F.contains(
"crypto") || F.contains(
"sha2");
778 llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
779 return F.contains(
"crypto") || F.contains(
"aes");
781 const bool FoundSHA2 = ItSHA2 != Features.rend();
782 const bool FoundAES = ItAES != Features.rend();
784 HasSHA2 = ItSHA2->take_front() ==
"+";
786 HasAES = ItAES->take_front() ==
"+";
787 if (ItCrypto != Features.rend()) {
788 if (HasSHA2 && HasAES)
789 Features.push_back(
"+crypto");
791 Features.push_back(
"-crypto");
793 Features.push_back(
"+sha2");
795 Features.push_back(
"-sha2");
797 Features.push_back(
"+aes");
799 Features.push_back(
"-aes");
802 if (HasSHA2 || HasAES) {
805 llvm::ARM::ProfileKind ArchProfile =
806 llvm::ARM::parseArchProfile(ArchSuffix);
807 if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) &&
808 (ArchProfile == llvm::ARM::ProfileKind::A ||
809 ArchProfile == llvm::ARM::ProfileKind::R))) {
811 D.Diag(clang::diag::warn_target_unsupported_extension)
813 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
815 D.Diag(clang::diag::warn_target_unsupported_extension)
817 << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
823 if (!Args.hasArg(options::OPT_fno_integrated_as)) {
824 Features.push_back(
"-sha2");
825 Features.push_back(
"-aes");
831 if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) {
832 StringRef FrameChainOption = A->getValue();
833 if (FrameChainOption.starts_with(
"aapcs"))
834 Features.push_back(
"+aapcs-frame-chain");
838 if (Args.getLastArg(options::OPT_mcmse))
839 Features.push_back(
"+8msecext");
841 if (Arg *A = Args.getLastArg(options::OPT_mfix_cmse_cve_2021_35465,
842 options::OPT_mno_fix_cmse_cve_2021_35465)) {
843 if (!Args.getLastArg(options::OPT_mcmse))
844 D.Diag(diag::err_opt_not_valid_without_opt)
845 << A->getOption().getName() <<
"-mcmse";
847 if (A->getOption().matches(options::OPT_mfix_cmse_cve_2021_35465))
848 Features.push_back(
"+fix-cmse-cve-2021-35465");
850 Features.push_back(
"-fix-cmse-cve-2021-35465");
854 if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a57_aes_1742098,
855 options::OPT_mno_fix_cortex_a57_aes_1742098)) {
856 if (A->getOption().matches(options::OPT_mfix_cortex_a57_aes_1742098)) {
857 Features.push_back(
"+fix-cortex-a57-aes-1742098");
859 Features.push_back(
"-fix-cortex-a57-aes-1742098");
866 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
867 options::OPT_mno_long_calls)) {
868 if (A->getOption().matches(options::OPT_mlong_calls))
869 Features.push_back(
"+long-calls");
870 }
else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
871 !Triple.isWatchOS() && !Triple.isXROS()) {
872 Features.push_back(
"+long-calls");
879 if (!ForAS && !ForMultilib) {
882 if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
883 if (A->getOption().matches(options::OPT_mexecute_only)) {
885 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2 &&
886 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6M)
887 D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
888 else if (llvm::ARM::parseArch(Triple.getArchName()) == llvm::ARM::ArchKind::ARMV6M) {
889 if (Arg *PIArg = Args.getLastArg(options::OPT_fropi, options::OPT_frwpi,
890 options::OPT_fpic, options::OPT_fpie,
891 options::OPT_fPIC, options::OPT_fPIE))
892 D.Diag(diag::err_opt_not_valid_with_opt_on_target)
893 << A->getAsString(Args) << PIArg->getAsString(Args) << Triple.getArchName();
894 }
else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
895 D.Diag(diag::err_opt_not_valid_with_opt)
896 << A->getAsString(Args) << B->getAsString(Args);
897 Features.push_back(
"+execute-only");
902 if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
903 options::OPT_munaligned_access,
904 options::OPT_mstrict_align,
905 options::OPT_mno_strict_align)) {
908 A->getOption().matches(options::OPT_mno_unaligned_access) ||
909 A->getOption().matches(options::OPT_mstrict_align)) {
910 Features.push_back(
"+strict-align");
913 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
914 D.Diag(diag::err_target_unsupported_unaligned) <<
"v6m";
917 else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
918 D.Diag(diag::err_target_unsupported_unaligned) <<
"v8m.base";
935 if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
936 if (VersionNum < 6 ||
937 Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
938 Features.push_back(
"+strict-align");
939 }
else if (Triple.getVendor() == llvm::Triple::Apple &&
940 Triple.isOSBinFormatMachO()) {
942 Features.push_back(
"+strict-align");
943 }
else if (VersionNum < 7 ||
944 Triple.getSubArch() ==
945 llvm::Triple::SubArchType::ARMSubArch_v6m ||
946 Triple.getSubArch() ==
947 llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) {
948 Features.push_back(
"+strict-align");
955 if (Args.hasArg(options::OPT_ffixed_r9))
956 Features.push_back(
"+reserve-r9");
959 if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
960 Features.push_back(
"+no-movt");
962 if (Args.hasArg(options::OPT_mno_neg_immediates))
963 Features.push_back(
"+no-neg-immediates");
966 if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
967 StringRef
Scope = A->getValue();
968 bool EnableRetBr =
false;
969 bool EnableBlr =
false;
970 bool DisableComdat =
false;
971 if (
Scope !=
"none") {
973 Scope.split(Opts,
",");
974 for (
auto Opt : Opts) {
981 if (Opt ==
"retbr") {
989 if (Opt ==
"comdat") {
990 DisableComdat =
false;
993 if (Opt ==
"nocomdat") {
994 DisableComdat =
true;
997 D.Diag(diag::err_drv_unsupported_option_argument)
998 << A->getSpelling() <<
Scope;
1003 if (EnableRetBr || EnableBlr)
1005 D.Diag(diag::err_sls_hardening_arm_not_supported)
1006 <<
Scope << A->getAsString(Args);
1009 Features.push_back(
"+harden-sls-retbr");
1011 Features.push_back(
"+harden-sls-blr");
1012 if (DisableComdat) {
1013 Features.push_back(
"+harden-sls-nocomdat");
1017 if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
1018 Features.push_back(
"+no-bti-at-return-twice");
1025std::string
arm::getARMArch(StringRef Arch,
const llvm::Triple &Triple) {
1028 MArch = std::string(Arch);
1030 MArch = std::string(Triple.getArchName());
1031 MArch = StringRef(MArch).split(
"+").first.lower();
1034 if (MArch ==
"native") {
1035 std::string CPU = std::string(llvm::sys::getHostCPUName());
1036 if (CPU !=
"generic") {
1044 MArch = std::string(
"arm") + Suffix.str();
1053 std::string MArch =
getARMArch(Arch, Triple);
1061 return llvm::ARM::getARMCPUForArch(Triple, MArch);
1066 const llvm::Triple &Triple) {
1070 std::string MCPU = StringRef(CPU).split(
"+").first.lower();
1072 if (MCPU ==
"native")
1073 return std::string(llvm::sys::getHostCPUName());
1086 const llvm::Triple &Triple) {
1087 llvm::ARM::ArchKind ArchKind;
1088 if (CPU ==
"generic" || CPU.empty()) {
1090 ArchKind = llvm::ARM::parseArch(ARMArch);
1091 if (ArchKind == llvm::ARM::ArchKind::INVALID)
1095 llvm::ARM::parseCPUArch(llvm::ARM::getARMCPUForArch(Triple, ARMArch));
1099 ArchKind = (Arch ==
"armv7k" || Arch ==
"thumbv7k")
1100 ? llvm::ARM::ArchKind::ARMV7K
1101 : llvm::ARM::parseCPUArch(CPU);
1110 const llvm::Triple &Triple) {
1111 llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple);
1112 if (ArchKind == llvm::ARM::ArchKind::INVALID)
1114 return llvm::ARM::getSubArch(ArchKind);
1118 const llvm::Triple &Triple) {
1119 if (Args.hasArg(options::OPT_r))
1125 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...
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
@ Generic
not a target-specific vector type