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(clang::driver::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();
 
  409  switch (Triple.getOS()) {
 
  410  case llvm::Triple::Darwin:
 
  411  case llvm::Triple::MacOSX:
 
  412  case llvm::Triple::IOS:
 
  413  case llvm::Triple::TvOS:
 
  414  case llvm::Triple::DriverKit:
 
  415  case llvm::Triple::XROS:
 
  417    if (Triple.isWatchABI())
 
  422  case llvm::Triple::WatchOS:
 
  426  case llvm::Triple::Win32:
 
  433  case llvm::Triple::NetBSD:
 
  434    switch (Triple.getEnvironment()) {
 
  435    case llvm::Triple::EABIHF:
 
  436    case llvm::Triple::GNUEABIHF:
 
  443  case llvm::Triple::FreeBSD:
 
  444    switch (Triple.getEnvironment()) {
 
  445    case llvm::Triple::GNUEABIHF:
 
  453  case llvm::Triple::Haiku:
 
  454  case llvm::Triple::OpenBSD:
 
  457  case llvm::Triple::Fuchsia:
 
  461    if (Triple.isOHOSFamily())
 
  463    switch (Triple.getEnvironment()) {
 
  464    case llvm::Triple::GNUEABIHF:
 
  465    case llvm::Triple::GNUEABIHFT64:
 
  466    case llvm::Triple::MuslEABIHF:
 
  467    case llvm::Triple::EABIHF:
 
  469    case llvm::Triple::Android:
 
  470    case llvm::Triple::GNUEABI:
 
  471    case llvm::Triple::GNUEABIT64:
 
  472    case llvm::Triple::MuslEABI:
 
  473    case llvm::Triple::EABI:
 
 
  486                                  const ArgList &Args) {
 
  489          Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
 
  490                          options::OPT_mfloat_abi_EQ)) {
 
  491    if (A->getOption().matches(options::OPT_msoft_float)) {
 
  492      ABI = FloatABI::Soft;
 
  493    } 
else if (A->getOption().matches(options::OPT_mhard_float)) {
 
  494      ABI = FloatABI::Hard;
 
  496      ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
 
  497                .Case(
"soft", FloatABI::Soft)
 
  498                .Case(
"softfp", FloatABI::SoftFP)
 
  499                .Case(
"hard", FloatABI::Hard)
 
  500                .Default(FloatABI::Invalid);
 
  501      if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
 
  502        D.
Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
 
  503        ABI = FloatABI::Soft;
 
  509  if (ABI == FloatABI::Invalid)
 
  512  if (ABI == FloatABI::Invalid) {
 
  514    if (Triple.isOSBinFormatMachO() &&
 
  515        Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
 
  516      ABI = FloatABI::Hard;
 
  518      ABI = FloatABI::Soft;
 
  520    if (Triple.getOS() != llvm::Triple::UnknownOS ||
 
  521        !Triple.isOSBinFormatMachO())
 
  522      D.
Diag(diag::warn_drv_assuming_mfloat_abi_is) << 
"soft";
 
  525  assert(ABI != FloatABI::Invalid && 
"must select an ABI");
 
  530  auto MVE = llvm::find(llvm::reverse(F), 
"+mve");
 
  531  auto NoMVE = llvm::find(llvm::reverse(F), 
"-mve");
 
  532  return MVE != F.rend() &&
 
  533         (NoMVE == F.rend() || std::distance(
MVE, NoMVE) > 0);
 
 
  537                                             const llvm::Triple &Triple,
 
  539                                             std::vector<StringRef> &Features,
 
  540                                             bool ForAS, 
bool ForMultilib) {
 
  542      Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
 
  544  std::optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv, WaArch;
 
  551  std::vector<StringRef> ExtensionFeatures;
 
  568      Features.push_back(
"+soft-float");
 
  572      Features.push_back(
"+soft-float-abi");
 
  577         Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
 
  580      for (StringRef 
Value : A->getValues()) {
 
  581        if (
Value.starts_with(
"-mfpu=")) {
 
  582          WaFPU = std::make_pair(A, 
Value.substr(6));
 
  583        } 
else if (
Value.starts_with(
"-mcpu=")) {
 
  584          WaCPU = std::make_pair(A, 
Value.substr(6));
 
  585        } 
else if (
Value.starts_with(
"-mhwdiv=")) {
 
  586          WaHDiv = std::make_pair(A, 
Value.substr(8));
 
  587        } 
else if (
Value.starts_with(
"-march=")) {
 
  588          WaArch = std::make_pair(A, 
Value.substr(7));
 
  596    if (Arg *A = Args.getLastArgNoClaim(options::OPT_mabi_EQ))
 
  597      A->ignoreTargetSpecific();
 
  602  if (TPMode == ReadTPMode::TPIDRURW)
 
  603    Features.push_back(
"+read-tp-tpidrurw");
 
  604  else if (TPMode == ReadTPMode::TPIDRPRW)
 
  605    Features.push_back(
"+read-tp-tpidrprw");
 
  606  else if (TPMode == ReadTPMode::TPIDRURO)
 
  607    Features.push_back(
"+read-tp-tpidruro");
 
  609  const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
 
  610  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
 
  613  llvm::ARM::FPUKind ArchArgFPUKind = llvm::ARM::FK_INVALID;
 
  614  llvm::ARM::FPUKind CPUArgFPUKind = llvm::ARM::FK_INVALID;
 
  619      D.
Diag(clang::diag::warn_drv_unused_argument)
 
  620          << CPUArg->getAsString(Args);
 
  621    CPUName = WaCPU->second;
 
  622    CPUArg = WaCPU->first;
 
  624    CPUName = CPUArg->getValue();
 
  629      D.
Diag(clang::diag::warn_drv_unused_argument)
 
  630          << ArchArg->getAsString(Args);
 
  631    ArchName = WaArch->second;
 
  634                     ExtensionFeatures, Triple, ArchArgFPUKind);
 
  637  } 
else if (ArchArg) {
 
  638    ArchName = ArchArg->getValue();
 
  640                     Triple, ArchArgFPUKind);
 
  644  if (CPUName == 
"native") {
 
  645    for (
auto &F : llvm::sys::getHostCPUFeatures())
 
  647          Args.MakeArgString((F.second ? 
"+" : 
"-") + F.first()));
 
  648  } 
else if (!CPUName.empty()) {
 
  658                    Triple, CPUArgFPUKind);
 
  662  (void)Args.getLastArg(options::OPT_mtune_EQ);
 
  665  llvm::ARM::FPUKind FPUKind = llvm::ARM::FK_INVALID;
 
  666  const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
 
  669      D.
Diag(clang::diag::warn_drv_unused_argument)
 
  670          << FPUArg->getAsString(Args);
 
  675    const char *AndroidFPU = 
"neon";
 
  676    FPUKind = llvm::ARM::parseFPU(AndroidFPU);
 
  677    if (!llvm::ARM::getFPUFeatures(FPUKind, Features))
 
  678      D.
Diag(clang::diag::err_drv_clang_unsupported)
 
  679          << std::string(
"-mfpu=") + AndroidFPU;
 
  680  } 
else if (ArchArgFPUKind != llvm::ARM::FK_INVALID ||
 
  681             CPUArgFPUKind != llvm::ARM::FK_INVALID) {
 
  683        CPUArgFPUKind != llvm::ARM::FK_INVALID ? CPUArgFPUKind : ArchArgFPUKind;
 
  684    (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
 
  688    if (
Generic && (Triple.isOSWindows() || Triple.isOSDarwin()) &&
 
  690      FPUKind = llvm::ARM::parseFPU(
"neon");
 
  692      llvm::ARM::ArchKind ArchKind =
 
  694      FPUKind = llvm::ARM::getDefaultFPU(CPU, ArchKind);
 
  696    (void)llvm::ARM::getFPUFeatures(FPUKind, Features);
 
  702  Features.insert(std::end(Features),
 
  703                  std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
 
  706  const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
 
  709      D.
Diag(clang::diag::warn_drv_unused_argument)
 
  710          << HDivArg->getAsString(Args);
 
  719  const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), 
"-fullfp16");
 
  720  const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), 
"+fp16fml");
 
  721  if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
 
  722    const auto ItRFullFP16  = std::find(Features.rbegin(), Features.rend(), 
"+fullfp16");
 
  723    if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
 
  726      if (std::find(Features.rbegin(), ItRFullFP16, 
"-fp16fml") == ItRFullFP16)
 
  727        Features.push_back(
"+fp16fml");
 
  730      goto fp16_fml_fallthrough;
 
  736    if (ItRNoFullFP16 < ItRFP16FML)
 
  737      Features.push_back(
"-fp16fml");
 
  738    else if (ItRNoFullFP16 > ItRFP16FML)
 
  739      Features.push_back(
"+fullfp16");
 
  746  bool HasFPRegs = 
true;
 
  748    llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
 
  752    Features.insert(Features.end(),
 
  753                    {
"-dotprod", 
"-fp16fml", 
"-bf16", 
"-mve", 
"-mve.fp"});
 
  755    FPUKind = llvm::ARM::FK_NONE;
 
  756  } 
else if (FPUKind == llvm::ARM::FK_NONE ||
 
  757             ArchArgFPUKind == llvm::ARM::FK_NONE ||
 
  758             CPUArgFPUKind == llvm::ARM::FK_NONE) {
 
  763    Features.insert(Features.end(),
 
  764                    {
"-dotprod", 
"-fp16fml", 
"-bf16", 
"-mve.fp"});
 
  766    FPUKind = llvm::ARM::FK_NONE;
 
  769    Features.emplace_back(
"-fpregs");
 
  772  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
 
  773    if (A->getOption().matches(options::OPT_mcrc))
 
  774      Features.push_back(
"+crc");
 
  776      Features.push_back(
"-crc");
 
  785  if (FPUKind == llvm::ARM::FK_FPV5_D16 || FPUKind == llvm::ARM::FK_FPV5_SP_D16)
 
  786    Features.push_back(
"-mve.fp");
 
  790  bool HasSimd = 
false;
 
  792      llvm::find_if(llvm::reverse(Features),
 
  793                    [](
const StringRef F) { 
return F.contains(
"neon"); });
 
  794  const bool FPUSupportsNeon = (llvm::ARM::FPUNames[FPUKind].NeonSupport ==
 
  795                                llvm::ARM::NeonSupportLevel::Neon) ||
 
  796                               (llvm::ARM::FPUNames[FPUKind].NeonSupport ==
 
  797                                llvm::ARM::NeonSupportLevel::Crypto);
 
  798  if (ItSimd != Features.rend())
 
  799    HasSimd = ItSimd->starts_with(
"+");
 
  800  if (!HasSimd && FPUSupportsNeon)
 
  801    Features.insert(Features.end(),
 
  802                    {
"-sha2", 
"-aes", 
"-crypto", 
"-dotprod", 
"-bf16", 
"-i8mm"});
 
  812  bool HasSHA2 = 
false;
 
  814  bool HasBF16 = 
false;
 
  815  bool HasDotprod = 
false;
 
  816  bool HasI8MM = 
false;
 
  817  const auto ItCrypto =
 
  818      llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
 
  819        return F.contains(
"crypto");
 
  822      llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
 
  823        return F.contains(
"crypto") || F.contains(
"sha2");
 
  826      llvm::find_if(llvm::reverse(Features), [](
const StringRef F) {
 
  827        return F.contains(
"crypto") || F.contains(
"aes");
 
  830      llvm::find_if(llvm::reverse(Features),
 
  831                    [](
const StringRef F) { 
return F.contains(
"bf16"); });
 
  832  const auto ItDotprod =
 
  833      llvm::find_if(llvm::reverse(Features),
 
  834                    [](
const StringRef F) { 
return F.contains(
"dotprod"); });
 
  836      llvm::find_if(llvm::reverse(Features),
 
  837                    [](
const StringRef F) { 
return F.contains(
"i8mm"); });
 
  838  if (ItSHA2 != Features.rend())
 
  839    HasSHA2 = ItSHA2->starts_with(
"+");
 
  840  if (ItAES != Features.rend())
 
  841    HasAES = ItAES->starts_with(
"+");
 
  842  if (ItBF16 != Features.rend())
 
  843    HasBF16 = ItBF16->starts_with(
"+");
 
  844  if (ItDotprod != Features.rend())
 
  845    HasDotprod = ItDotprod->starts_with(
"+");
 
  846  if (ItI8MM != Features.rend())
 
  847    HasI8MM = ItI8MM->starts_with(
"+");
 
  848  if (ItCrypto != Features.rend()) {
 
  849    if (HasSHA2 && HasAES)
 
  850      Features.push_back(
"+crypto");
 
  852      Features.push_back(
"-crypto");
 
  854      Features.push_back(
"+sha2");
 
  856      Features.push_back(
"-sha2");
 
  858      Features.push_back(
"+aes");
 
  860      Features.push_back(
"-aes");
 
  863  if (HasAES || HasSHA2 || HasBF16 || HasDotprod || HasI8MM)
 
  864    Features.push_back(
"+neon");
 
  866  if (HasSHA2 || HasAES) {
 
  869    llvm::ARM::ProfileKind ArchProfile =
 
  870        llvm::ARM::parseArchProfile(ArchSuffix);
 
  871    if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) &&
 
  872          (ArchProfile == llvm::ARM::ProfileKind::A ||
 
  873           ArchProfile == llvm::ARM::ProfileKind::R))) {
 
  875        D.
Diag(clang::diag::warn_target_unsupported_extension)
 
  877            << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
 
  879        D.
Diag(clang::diag::warn_target_unsupported_extension)
 
  881            << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
 
  887      if (!Args.hasArg(options::OPT_fno_integrated_as)) {
 
  888        Features.push_back(
"-sha2");
 
  889        Features.push_back(
"-aes");
 
  895  if (Arg *A = Args.getLastArg(options::OPT_mframe_chain)) {
 
  896    StringRef FrameChainOption = A->getValue();
 
  897    if (FrameChainOption.starts_with(
"aapcs"))
 
  898      Features.push_back(
"+aapcs-frame-chain");
 
  902  if (Args.getLastArg(options::OPT_mcmse))
 
  903    Features.push_back(
"+8msecext");
 
  905  if (Arg *A = Args.getLastArg(options::OPT_mfix_cmse_cve_2021_35465,
 
  906                               options::OPT_mno_fix_cmse_cve_2021_35465)) {
 
  907    if (!Args.getLastArg(options::OPT_mcmse))
 
  908      D.
Diag(diag::err_opt_not_valid_without_opt)
 
  909          << A->getOption().getName() << 
"-mcmse";
 
  911    if (A->getOption().matches(options::OPT_mfix_cmse_cve_2021_35465))
 
  912      Features.push_back(
"+fix-cmse-cve-2021-35465");
 
  914      Features.push_back(
"-fix-cmse-cve-2021-35465");
 
  918  if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a57_aes_1742098,
 
  919                               options::OPT_mno_fix_cortex_a57_aes_1742098)) {
 
  920    if (A->getOption().matches(options::OPT_mfix_cortex_a57_aes_1742098)) {
 
  921      Features.push_back(
"+fix-cortex-a57-aes-1742098");
 
  923      Features.push_back(
"-fix-cortex-a57-aes-1742098");
 
  930  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
 
  931                               options::OPT_mno_long_calls)) {
 
  932    if (A->getOption().matches(options::OPT_mlong_calls))
 
  933      Features.push_back(
"+long-calls");
 
  934  } 
else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
 
  935             !Triple.isWatchOS() && !Triple.isXROS()) {
 
  936    Features.push_back(
"+long-calls");
 
  943  if (!ForAS && !ForMultilib) {
 
  946    if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
 
  947      if (A->getOption().matches(options::OPT_mexecute_only)) {
 
  949            llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2 &&
 
  950            llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6M)
 
  951              D.
Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
 
  952        else if (llvm::ARM::parseArch(Triple.getArchName()) == llvm::ARM::ArchKind::ARMV6M) {
 
  953          if (Arg *PIArg = Args.getLastArg(options::OPT_fropi, options::OPT_frwpi,
 
  954                                           options::OPT_fpic, options::OPT_fpie,
 
  955                                           options::OPT_fPIC, options::OPT_fPIE))
 
  956            D.
Diag(diag::err_opt_not_valid_with_opt_on_target)
 
  957                << A->getAsString(Args) << PIArg->getAsString(Args) << Triple.getArchName();
 
  958        } 
else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
 
  959          D.
Diag(diag::err_opt_not_valid_with_opt)
 
  960              << A->getAsString(Args) << B->getAsString(Args);
 
  961        Features.push_back(
"+execute-only");
 
  966  if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
 
  967                                      options::OPT_munaligned_access,
 
  968                                      options::OPT_mstrict_align,
 
  969                                      options::OPT_mno_strict_align)) {
 
  972        A->getOption().matches(options::OPT_mno_unaligned_access) ||
 
  973        A->getOption().matches(options::OPT_mstrict_align)) {
 
  974      Features.push_back(
"+strict-align");
 
  977      if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
 
  978        D.
Diag(diag::err_target_unsupported_unaligned) << 
"v6m";
 
  981      else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
 
  982        D.
Diag(diag::err_target_unsupported_unaligned) << 
"v8m.base";
 
  999    if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
 
 1000      if (VersionNum < 6 ||
 
 1001          Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
 
 1002        Features.push_back(
"+strict-align");
 
 1003    } 
else if (Triple.getVendor() == llvm::Triple::Apple &&
 
 1004               Triple.isOSBinFormatMachO()) {
 
 1006      Features.push_back(
"+strict-align");
 
 1007    } 
else if (VersionNum < 7 ||
 
 1008               Triple.getSubArch() ==
 
 1009                   llvm::Triple::SubArchType::ARMSubArch_v6m ||
 
 1010               Triple.getSubArch() ==
 
 1011                   llvm::Triple::SubArchType::ARMSubArch_v8m_baseline) {
 
 1012      Features.push_back(
"+strict-align");
 
 1019  if (Args.hasArg(options::OPT_ffixed_r9))
 
 1020    Features.push_back(
"+reserve-r9");
 
 1023  if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
 
 1024    Features.push_back(
"+no-movt");
 
 1026  if (Args.hasArg(options::OPT_mno_neg_immediates))
 
 1027    Features.push_back(
"+no-neg-immediates");
 
 1030  if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
 
 1031    StringRef 
Scope = A->getValue();
 
 1032    bool EnableRetBr = 
false;
 
 1033    bool EnableBlr = 
false;
 
 1034    bool DisableComdat = 
false;
 
 1035    if (
Scope != 
"none") {
 
 1037      Scope.split(Opts, 
",");
 
 1038      for (
auto Opt : Opts) {
 
 1045        if (Opt == 
"retbr") {
 
 1053        if (Opt == 
"comdat") {
 
 1054          DisableComdat = 
false;
 
 1057        if (Opt == 
"nocomdat") {
 
 1058          DisableComdat = 
true;
 
 1061        D.
Diag(diag::err_drv_unsupported_option_argument)
 
 1062            << A->getSpelling() << 
Scope;
 
 1067    if (EnableRetBr || EnableBlr)
 
 1069        D.
Diag(diag::err_sls_hardening_arm_not_supported)
 
 1070            << 
Scope << A->getAsString(Args);
 
 1073      Features.push_back(
"+harden-sls-retbr");
 
 1075      Features.push_back(
"+harden-sls-blr");
 
 1076    if (DisableComdat) {
 
 1077      Features.push_back(
"+harden-sls-nocomdat");
 
 1081  if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
 
 1082    Features.push_back(
"+no-bti-at-return-twice");
 
 1092    MArch = std::string(
Arch);
 
 1094    MArch = std::string(Triple.getArchName());
 
 1095  MArch = StringRef(MArch).split(
"+").first.lower();
 
 1098  if (MArch == 
"native") {
 
 1099    std::string 
CPU = std::string(llvm::sys::getHostCPUName());
 
 1100    if (CPU != 
"generic") {
 
 1108        MArch = std::string(
"arm") + Suffix.str();
 
 1125  return llvm::ARM::getARMCPUForArch(Triple, MArch);
 
 1130                                 const llvm::Triple &Triple) {
 
 1134    std::string MCPU = StringRef(CPU).split(
"+").first.lower();
 
 1136    if (MCPU == 
"native")
 
 1137      return std::string(llvm::sys::getHostCPUName());
 
 1150                                               const llvm::Triple &Triple) {
 
 1151  llvm::ARM::ArchKind ArchKind;
 
 1152  if (CPU == 
"generic" || CPU.empty()) {
 
 1154    ArchKind = llvm::ARM::parseArch(ARMArch);
 
 1155    if (ArchKind == llvm::ARM::ArchKind::INVALID)
 
 1159          llvm::ARM::parseCPUArch(llvm::ARM::getARMCPUForArch(Triple, ARMArch));
 
 1163    ArchKind = (
Arch == 
"armv7k" || 
Arch == 
"thumbv7k")
 
 1164                          ? llvm::ARM::ArchKind::ARMV7K
 
 1165                          : llvm::ARM::parseCPUArch(CPU);
 
 
 1174                                       const llvm::Triple &Triple) {
 
 1175  llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, 
Arch, Triple);
 
 1176  if (ArchKind == llvm::ARM::ArchKind::INVALID)
 
 1178  return llvm::ARM::getSubArch(ArchKind);
 
 1182                            const llvm::Triple &Triple) {
 
 1183  if (Args.hasArg(options::OPT_r))
 
 1189    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
@ Generic
not a target-specific vector type