13 #include "llvm/ADT/StringSwitch.h" 14 #include "llvm/Option/ArgList.h" 15 #include "llvm/Support/TargetParser.h" 19 using namespace clang;
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;
36 llvm::StringRef &CPU,
bool FromAs) {
37 if (
const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
39 if (
const Arg *A = Args.getLastArg(options::OPT_march_EQ))
45 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
46 StringRef
Value = A->getValue();
47 if (Value.startswith(
"-mcpu="))
48 CPU = Value.substr(6);
49 if (Value.startswith(
"-march="))
50 Arch = Value.substr(7);
57 const ArgList &Args, StringRef HWDiv,
58 std::vector<StringRef> &Features) {
59 unsigned HWDivID = llvm::ARM::parseHWDiv(HWDiv);
60 if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
61 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
66 const ArgList &Args, StringRef FPU,
67 std::vector<StringRef> &Features) {
68 unsigned FPUID = llvm::ARM::parseFPU(FPU);
69 if (!llvm::ARM::getFPUFeatures(FPUID, Features))
70 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
75 StringRef CPU, llvm::ARM::ArchKind ArchKind,
76 std::vector<StringRef> &Features) {
78 text.split(Split, StringRef(
"+"), -1,
false);
80 for (StringRef Feature : Split) {
81 if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features))
88 std::vector<StringRef> &Features) {
89 CPU = CPU.split(
"+").first;
90 if (CPU !=
"generic") {
91 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
92 unsigned Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
101 llvm::StringRef ArchName, llvm::StringRef CPUName,
102 std::vector<StringRef> &Features,
103 const llvm::Triple &Triple) {
104 std::pair<StringRef, StringRef>
Split = ArchName.split(
"+");
107 llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
108 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
110 D, Split.second, CPUName, ArchKind, Features)))
111 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
116 llvm::StringRef CPUName, llvm::StringRef ArchName,
117 std::vector<StringRef> &Features,
118 const llvm::Triple &Triple) {
119 std::pair<StringRef, StringRef>
Split = CPUName.split(
"+");
122 llvm::ARM::ArchKind ArchKind =
124 if (ArchKind == llvm::ARM::ArchKind::INVALID ||
126 D, Split.second, CPU, ArchKind, Features)))
127 D.
Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
133 return T.getEnvironment() == llvm::Triple::EABI ||
139 if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
142 llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
143 .Case(
"cp15", ReadTPMode::Cp15)
144 .Case(
"soft", ReadTPMode::Soft)
145 .Default(ReadTPMode::Invalid);
146 if (ThreadPointer != ReadTPMode::Invalid)
147 return ThreadPointer;
148 if (StringRef(A->getValue()).empty())
149 D.
Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
151 D.
Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
152 return ReadTPMode::Invalid;
154 return ReadTPMode::Soft;
165 Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
166 options::OPT_mfloat_abi_EQ)) {
167 if (A->getOption().matches(options::OPT_msoft_float)) {
168 ABI = FloatABI::Soft;
169 }
else if (A->getOption().matches(options::OPT_mhard_float)) {
170 ABI = FloatABI::Hard;
172 ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
173 .Case(
"soft", FloatABI::Soft)
174 .Case(
"softfp", FloatABI::SoftFP)
175 .Case(
"hard", FloatABI::Hard)
176 .Default(FloatABI::Invalid);
177 if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
178 D.
Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
179 ABI = FloatABI::Soft;
186 ABI == FloatABI::Hard) {
187 D.
Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args)
188 << Triple.getArchName();
193 if (ABI == FloatABI::Invalid) {
194 switch (Triple.getOS()) {
195 case llvm::Triple::Darwin:
196 case llvm::Triple::MacOSX:
197 case llvm::Triple::IOS:
198 case llvm::Triple::TvOS: {
200 ABI = (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
201 ABI = Triple.isWatchABI() ? FloatABI::Hard : ABI;
204 case llvm::Triple::WatchOS:
205 ABI = FloatABI::Hard;
209 case llvm::Triple::Win32:
210 ABI = FloatABI::Hard;
213 case llvm::Triple::NetBSD:
214 switch (Triple.getEnvironment()) {
215 case llvm::Triple::EABIHF:
216 case llvm::Triple::GNUEABIHF:
217 ABI = FloatABI::Hard;
220 ABI = FloatABI::Soft;
225 case llvm::Triple::FreeBSD:
226 switch (Triple.getEnvironment()) {
227 case llvm::Triple::GNUEABIHF:
228 ABI = FloatABI::Hard;
232 ABI = FloatABI::Soft;
237 case llvm::Triple::OpenBSD:
238 ABI = FloatABI::SoftFP;
242 switch (Triple.getEnvironment()) {
243 case llvm::Triple::GNUEABIHF:
244 case llvm::Triple::MuslEABIHF:
245 case llvm::Triple::EABIHF:
246 ABI = FloatABI::Hard;
248 case llvm::Triple::GNUEABI:
249 case llvm::Triple::MuslEABI:
250 case llvm::Triple::EABI:
252 ABI = FloatABI::SoftFP;
254 case llvm::Triple::Android:
255 ABI = (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft;
259 if (Triple.isOSBinFormatMachO() &&
260 Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
261 ABI = FloatABI::Hard;
263 ABI = FloatABI::Soft;
265 if (Triple.getOS() != llvm::Triple::UnknownOS ||
266 !Triple.isOSBinFormatMachO())
267 D.
Diag(diag::warn_drv_assuming_mfloat_abi_is) <<
"soft";
273 assert(ABI != FloatABI::Invalid &&
"must select an ABI");
278 const llvm::Triple &Triple,
280 ArgStringList &CmdArgs,
281 std::vector<StringRef> &Features,
286 Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
289 const Arg *WaCPU =
nullptr, *WaFPU =
nullptr;
290 const Arg *WaHDiv =
nullptr, *WaArch =
nullptr;
297 std::vector<StringRef> ExtensionFeatures;
314 Features.push_back(
"+soft-float");
318 Features.push_back(
"+soft-float-abi");
323 Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
324 StringRef
Value = A->getValue();
325 if (Value.startswith(
"-mfpu=")) {
327 }
else if (Value.startswith(
"-mcpu=")) {
329 }
else if (Value.startswith(
"-mhwdiv=")) {
331 }
else if (Value.startswith(
"-march=")) {
338 Features.push_back(
"+read-tp-hard");
340 const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
341 const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
348 D.
Diag(clang::diag::warn_drv_unused_argument)
349 << CPUArg->getAsString(Args);
350 CPUName = StringRef(WaCPU->getValue()).substr(6);
353 CPUName = CPUArg->getValue();
358 D.
Diag(clang::diag::warn_drv_unused_argument)
359 << ArchArg->getAsString(Args);
360 ArchName = StringRef(WaArch->getValue()).substr(7);
362 ExtensionFeatures, Triple);
364 D.
Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
365 }
else if (ArchArg) {
366 ArchName = ArchArg->getValue();
368 ExtensionFeatures, Triple);
372 if (CPUName ==
"native") {
373 llvm::StringMap<bool> HostFeatures;
374 if (llvm::sys::getHostCPUFeatures(HostFeatures))
375 for (
auto &F : HostFeatures)
377 Args.MakeArgString((F.second ?
"+" :
"-") + F.first()));
378 }
else if (!CPUName.empty()) {
388 ExtensionFeatures, Triple);
390 const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
393 D.
Diag(clang::diag::warn_drv_unused_argument)
394 << FPUArg->getAsString(Args);
400 const char *AndroidFPU =
"neon";
401 if (!llvm::ARM::getFPUFeatures(llvm::ARM::parseFPU(AndroidFPU), Features))
402 D.
Diag(clang::diag::err_drv_clang_unsupported)
403 << std::string(
"-mfpu=") + AndroidFPU;
409 Features.insert(std::end(Features),
410 std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
413 const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
416 D.
Diag(clang::diag::warn_drv_unused_argument)
417 << HDivArg->getAsString(Args);
419 StringRef(WaHDiv->getValue()).substr(8), Features);
427 const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(),
"-fullfp16");
428 const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(),
"+fp16fml");
429 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
430 const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(),
"+fullfp16");
431 if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
434 if (std::find(Features.rbegin(), ItRFullFP16,
"-fp16fml") == ItRFullFP16)
435 Features.push_back(
"+fp16fml");
438 goto fp16_fml_fallthrough;
441 fp16_fml_fallthrough:
444 if (ItRNoFullFP16 < ItRFP16FML)
445 Features.push_back(
"-fp16fml");
446 else if (ItRNoFullFP16 > ItRFP16FML)
447 Features.push_back(
"+fullfp16");
454 llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
462 for (std::string Feature : {
463 "vfp2",
"vfp2sp",
"vfp2d16",
"vfp2d16sp",
464 "vfp3",
"vfp3sp",
"vfp3d16",
"vfp3d16sp",
465 "vfp4",
"vfp4sp",
"vfp4d16",
"vfp4d16sp",
466 "fp-armv8",
"fp-armv8sp",
"fp-armv8d16",
"fp-armv8d16sp",
467 "fullfp16",
"neon",
"crypto",
"dotprod",
"fp16fml",
468 "fp64",
"d32",
"fpregs"})
469 Features.push_back(Args.MakeArgString(
"-" + Feature));
473 if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
474 if (A->getOption().matches(options::OPT_mcrc))
475 Features.push_back(
"+crc");
477 Features.push_back(
"-crc");
482 if (ArchName.find_lower(
"armv8a") != StringRef::npos ||
483 ArchName.find_lower(
"armv8.1a") != StringRef::npos ||
484 ArchName.find_lower(
"armv8.2a") != StringRef::npos ||
485 ArchName.find_lower(
"armv8.3a") != StringRef::npos ||
486 ArchName.find_lower(
"armv8.4a") != StringRef::npos) {
487 if (ArchName.find_lower(
"+crypto") != StringRef::npos) {
488 if (ArchName.find_lower(
"+nosha2") == StringRef::npos)
489 Features.push_back(
"+sha2");
490 if (ArchName.find_lower(
"+noaes") == StringRef::npos)
491 Features.push_back(
"+aes");
492 }
else if (ArchName.find_lower(
"-crypto") != StringRef::npos) {
493 if (ArchName.find_lower(
"+sha2") == StringRef::npos)
494 Features.push_back(
"-sha2");
495 if (ArchName.find_lower(
"+aes") == StringRef::npos)
496 Features.push_back(
"-aes");
501 if (Args.getLastArg(options::OPT_mcmse))
502 Features.push_back(
"+8msecext");
507 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
508 options::OPT_mno_long_calls)) {
509 if (A->getOption().matches(options::OPT_mlong_calls))
510 Features.push_back(
"+long-calls");
511 }
else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
512 !Triple.isWatchOS()) {
513 Features.push_back(
"+long-calls");
521 if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
522 if (A->getOption().matches(options::OPT_mexecute_only)) {
524 llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2)
525 D.
Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
526 else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
527 D.
Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
531 else if (Arg *B = Args.getLastArg(options::OPT_mlong_calls, options::OPT_mno_long_calls)) {
532 if (B->getOption().matches(options::OPT_mlong_calls))
533 D.
Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
535 Features.push_back(
"+execute-only");
542 Features.push_back(
"+strict-align");
543 else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
544 options::OPT_munaligned_access)) {
545 if (A->getOption().matches(options::OPT_munaligned_access)) {
547 if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
548 D.
Diag(diag::err_target_unsupported_unaligned) <<
"v6m";
551 else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
552 D.
Diag(diag::err_target_unsupported_unaligned) <<
"v8m.base";
554 Features.push_back(
"+strict-align");
570 if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
571 if (VersionNum < 6 ||
572 Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
573 Features.push_back(
"+strict-align");
574 }
else if (Triple.isOSLinux() || Triple.isOSNaCl()) {
576 Features.push_back(
"+strict-align");
578 Features.push_back(
"+strict-align");
584 if (Args.hasArg(options::OPT_ffixed_r9))
585 Features.push_back(
"+reserve-r9");
588 if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
589 Features.push_back(
"+no-movt");
591 if (Args.hasArg(options::OPT_mno_neg_immediates))
592 Features.push_back(
"+no-neg-immediates");
595 const std::string
arm::getARMArch(StringRef Arch,
const llvm::Triple &Triple) {
600 MArch = Triple.getArchName();
601 MArch = StringRef(MArch).split(
"+").first.lower();
604 if (MArch ==
"native") {
605 std::string CPU = llvm::sys::getHostCPUName();
606 if (CPU !=
"generic") {
614 MArch = std::string(
"arm") + Suffix.str();
631 return Triple.getARMCPUForArch(MArch);
636 const llvm::Triple &Triple) {
640 std::string MCPU = StringRef(CPU).split(
"+").first.lower();
642 if (MCPU ==
"native")
643 return llvm::sys::getHostCPUName();
656 const llvm::Triple &Triple) {
657 llvm::ARM::ArchKind ArchKind;
658 if (CPU ==
"generic") {
660 ArchKind = llvm::ARM::parseArch(ARMArch);
661 if (ArchKind == llvm::ARM::ArchKind::INVALID)
664 ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
668 ArchKind = (Arch ==
"armv7k" || Arch ==
"thumbv7k")
669 ? llvm::ARM::ArchKind::ARMV7K
670 : llvm::ARM::parseCPUArch(CPU);
679 const llvm::Triple &Triple) {
681 if (ArchKind == llvm::ARM::ArchKind::INVALID)
683 return llvm::ARM::getSubArch(ArchKind);
687 const llvm::Triple &Triple) {
688 if (Args.hasArg(options::OPT_r))
694 CmdArgs.push_back(
"--be8");
DiagnosticBuilder Diag(unsigned DiagID) const
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Dataflow Directional Tag Classes.