Home | History | Annotate | Line # | Download | only in Arch
      1 //===--- ARM.cpp - ARM (not AArch64) Helpers for Tools ----------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 
      9 #include "ARM.h"
     10 #include "clang/Driver/Driver.h"
     11 #include "clang/Driver/DriverDiagnostic.h"
     12 #include "clang/Driver/Options.h"
     13 #include "llvm/ADT/StringSwitch.h"
     14 #include "llvm/Option/ArgList.h"
     15 #include "llvm/Support/TargetParser.h"
     16 #include "llvm/Support/Host.h"
     17 
     18 using namespace clang::driver;
     19 using namespace clang::driver::tools;
     20 using namespace clang;
     21 using namespace llvm::opt;
     22 
     23 // Get SubArch (vN).
     24 int arm::getARMSubArchVersionNumber(const llvm::Triple &Triple) {
     25   llvm::StringRef Arch = Triple.getArchName();
     26   return llvm::ARM::parseArchVersion(Arch);
     27 }
     28 
     29 // True if M-profile.
     30 bool arm::isARMMProfile(const llvm::Triple &Triple) {
     31   llvm::StringRef Arch = Triple.getArchName();
     32   return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::M;
     33 }
     34 
     35 // True if A-profile.
     36 bool arm::isARMAProfile(const llvm::Triple &Triple) {
     37   llvm::StringRef Arch = Triple.getArchName();
     38   return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A;
     39 }
     40 
     41 // Get Arch/CPU from args.
     42 void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
     43                                 llvm::StringRef &CPU, bool FromAs) {
     44   if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
     45     CPU = A->getValue();
     46   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
     47     Arch = A->getValue();
     48   if (!FromAs)
     49     return;
     50 
     51   for (const Arg *A :
     52        Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
     53     // Use getValues because -Wa can have multiple arguments
     54     // e.g. -Wa,-mcpu=foo,-mcpu=bar
     55     for (StringRef Value : A->getValues()) {
     56       if (Value.startswith("-mcpu="))
     57         CPU = Value.substr(6);
     58       if (Value.startswith("-march="))
     59         Arch = Value.substr(7);
     60     }
     61   }
     62 }
     63 
     64 // Handle -mhwdiv=.
     65 // FIXME: Use ARMTargetParser.
     66 static void getARMHWDivFeatures(const Driver &D, const Arg *A,
     67                                 const ArgList &Args, StringRef HWDiv,
     68                                 std::vector<StringRef> &Features) {
     69   uint64_t HWDivID = llvm::ARM::parseHWDiv(HWDiv);
     70   if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
     71     D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
     72 }
     73 
     74 // Handle -mfpu=.
     75 static unsigned getARMFPUFeatures(const Driver &D, const Arg *A,
     76                                   const ArgList &Args, StringRef FPU,
     77                                   std::vector<StringRef> &Features) {
     78   unsigned FPUID = llvm::ARM::parseFPU(FPU);
     79   if (!llvm::ARM::getFPUFeatures(FPUID, Features))
     80     D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
     81   return FPUID;
     82 }
     83 
     84 // Decode ARM features from string like +[no]featureA+[no]featureB+...
     85 static bool DecodeARMFeatures(const Driver &D, StringRef text, StringRef CPU,
     86                               llvm::ARM::ArchKind ArchKind,
     87                               std::vector<StringRef> &Features,
     88                               unsigned &ArgFPUID) {
     89   SmallVector<StringRef, 8> Split;
     90   text.split(Split, StringRef("+"), -1, false);
     91 
     92   for (StringRef Feature : Split) {
     93     if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features, ArgFPUID))
     94       return false;
     95   }
     96   return true;
     97 }
     98 
     99 static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU,
    100                                      std::vector<StringRef> &Features) {
    101   CPU = CPU.split("+").first;
    102   if (CPU != "generic") {
    103     llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
    104     uint64_t Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
    105     llvm::ARM::getExtensionFeatures(Extension, Features);
    106   }
    107 }
    108 
    109 // Check if -march is valid by checking if it can be canonicalised and parsed.
    110 // getARMArch is used here instead of just checking the -march value in order
    111 // to handle -march=native correctly.
    112 static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
    113                              llvm::StringRef ArchName, llvm::StringRef CPUName,
    114                              std::vector<StringRef> &Features,
    115                              const llvm::Triple &Triple, unsigned &ArgFPUID) {
    116   std::pair<StringRef, StringRef> Split = ArchName.split("+");
    117 
    118   std::string MArch = arm::getARMArch(ArchName, Triple);
    119   llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
    120   if (ArchKind == llvm::ARM::ArchKind::INVALID ||
    121       (Split.second.size() && !DecodeARMFeatures(D, Split.second, CPUName,
    122                                                  ArchKind, Features, ArgFPUID)))
    123     D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
    124 }
    125 
    126 // Check -mcpu=. Needs ArchName to handle -mcpu=generic.
    127 static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
    128                             llvm::StringRef CPUName, llvm::StringRef ArchName,
    129                             std::vector<StringRef> &Features,
    130                             const llvm::Triple &Triple, unsigned &ArgFPUID) {
    131   std::pair<StringRef, StringRef> Split = CPUName.split("+");
    132 
    133   std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
    134   llvm::ARM::ArchKind ArchKind =
    135     arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
    136   if (ArchKind == llvm::ARM::ArchKind::INVALID ||
    137       (Split.second.size() &&
    138        !DecodeARMFeatures(D, Split.second, CPU, ArchKind, Features, ArgFPUID)))
    139     D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
    140 }
    141 
    142 bool arm::useAAPCSForMachO(const llvm::Triple &T) {
    143   // The backend is hardwired to assume AAPCS for M-class processors, ensure
    144   // the frontend matches that.
    145   return T.getEnvironment() == llvm::Triple::EABI ||
    146          T.getEnvironment() == llvm::Triple::EABIHF ||
    147          T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
    148 }
    149 
    150 // Select mode for reading thread pointer (-mtp=soft/cp15).
    151 arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args) {
    152   if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
    153     arm::ReadTPMode ThreadPointer =
    154         llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
    155             .Case("cp15", ReadTPMode::Cp15)
    156             .Case("soft", ReadTPMode::Soft)
    157             .Default(ReadTPMode::Invalid);
    158     if (ThreadPointer != ReadTPMode::Invalid)
    159       return ThreadPointer;
    160     if (StringRef(A->getValue()).empty())
    161       D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
    162     else
    163       D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
    164     return ReadTPMode::Invalid;
    165   }
    166   return ReadTPMode::Soft;
    167 }
    168 
    169 void arm::setArchNameInTriple(const Driver &D, const ArgList &Args,
    170                               types::ID InputType, llvm::Triple &Triple) {
    171   StringRef MCPU, MArch;
    172   if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
    173     MCPU = A->getValue();
    174   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
    175     MArch = A->getValue();
    176 
    177   std::string CPU = Triple.isOSBinFormatMachO()
    178                         ? tools::arm::getARMCPUForMArch(MArch, Triple).str()
    179                         : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);
    180   StringRef Suffix = tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
    181 
    182   bool IsBigEndian = Triple.getArch() == llvm::Triple::armeb ||
    183                      Triple.getArch() == llvm::Triple::thumbeb;
    184   // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
    185   // '-mbig-endian'/'-EB'.
    186   if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
    187                                options::OPT_mbig_endian)) {
    188     IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
    189   }
    190   std::string ArchName = IsBigEndian ? "armeb" : "arm";
    191 
    192   // FIXME: Thumb should just be another -target-feaure, not in the triple.
    193   bool IsMProfile =
    194       llvm::ARM::parseArchProfile(Suffix) == llvm::ARM::ProfileKind::M;
    195   bool ThumbDefault = IsMProfile ||
    196                       // Thumb2 is the default for V7 on Darwin.
    197                       (llvm::ARM::parseArchVersion(Suffix) == 7 &&
    198                        Triple.isOSBinFormatMachO()) ||
    199                       // FIXME: this is invalid for WindowsCE
    200                       Triple.isOSWindows();
    201 
    202   // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for
    203   // M-Class CPUs/architecture variants, which is not supported.
    204   bool ARMModeRequested =
    205       !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
    206   if (IsMProfile && ARMModeRequested) {
    207     if (MCPU.size())
    208       D.Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM";
    209     else
    210       D.Diag(diag::err_arch_unsupported_isa)
    211           << tools::arm::getARMArch(MArch, Triple) << "ARM";
    212   }
    213 
    214   // Check to see if an explicit choice to use thumb has been made via
    215   // -mthumb. For assembler files we must check for -mthumb in the options
    216   // passed to the assembler via -Wa or -Xassembler.
    217   bool IsThumb = false;
    218   if (InputType != types::TY_PP_Asm)
    219     IsThumb =
    220         Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
    221   else {
    222     // Ideally we would check for these flags in
    223     // CollectArgsForIntegratedAssembler but we can't change the ArchName at
    224     // that point.
    225     llvm::StringRef WaMArch, WaMCPU;
    226     for (const auto *A :
    227          Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
    228       for (StringRef Value : A->getValues()) {
    229         // There is no assembler equivalent of -mno-thumb, -marm, or -mno-arm.
    230         if (Value == "-mthumb")
    231           IsThumb = true;
    232         else if (Value.startswith("-march="))
    233           WaMArch = Value.substr(7);
    234         else if (Value.startswith("-mcpu="))
    235           WaMCPU = Value.substr(6);
    236       }
    237     }
    238 
    239     if (WaMCPU.size() || WaMArch.size()) {
    240       // The way this works means that we prefer -Wa,-mcpu's architecture
    241       // over -Wa,-march. Which matches the compiler behaviour.
    242       Suffix = tools::arm::getLLVMArchSuffixForARM(WaMCPU, WaMArch, Triple);
    243     }
    244   }
    245 
    246   // Assembly files should start in ARM mode, unless arch is M-profile, or
    247   // -mthumb has been passed explicitly to the assembler. Windows is always
    248   // thumb.
    249   if (IsThumb || IsMProfile || Triple.isOSWindows()) {
    250     if (IsBigEndian)
    251       ArchName = "thumbeb";
    252     else
    253       ArchName = "thumb";
    254   }
    255   Triple.setArchName(ArchName + Suffix.str());
    256 }
    257 
    258 void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args,
    259                               llvm::Triple &Triple) {
    260   bool isHardFloat =
    261       (arm::getARMFloatABI(D, Triple, Args) == arm::FloatABI::Hard);
    262 
    263   switch (Triple.getEnvironment()) {
    264   case llvm::Triple::GNUEABI:
    265   case llvm::Triple::GNUEABIHF:
    266     Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHF
    267                                       : llvm::Triple::GNUEABI);
    268     break;
    269   case llvm::Triple::EABI:
    270   case llvm::Triple::EABIHF:
    271     Triple.setEnvironment(isHardFloat ? llvm::Triple::EABIHF
    272                                       : llvm::Triple::EABI);
    273     break;
    274   case llvm::Triple::MuslEABI:
    275   case llvm::Triple::MuslEABIHF:
    276     Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF
    277                                       : llvm::Triple::MuslEABI);
    278     break;
    279   default: {
    280     arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple);
    281     if (DefaultABI != arm::FloatABI::Invalid &&
    282         isHardFloat != (DefaultABI == arm::FloatABI::Hard)) {
    283       Arg *ABIArg =
    284           Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
    285                           options::OPT_mfloat_abi_EQ);
    286       assert(ABIArg && "Non-default float abi expected to be from arg");
    287       D.Diag(diag::err_drv_unsupported_opt_for_target)
    288           << ABIArg->getAsString(Args) << Triple.getTriple();
    289     }
    290     break;
    291   }
    292   }
    293 }
    294 
    295 arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
    296   return arm::getARMFloatABI(TC.getDriver(), TC.getEffectiveTriple(), Args);
    297 }
    298 
    299 arm::FloatABI arm::getDefaultFloatABI(const llvm::Triple &Triple) {
    300   auto SubArch = getARMSubArchVersionNumber(Triple);
    301   switch (Triple.getOS()) {
    302   case llvm::Triple::Darwin:
    303   case llvm::Triple::MacOSX:
    304   case llvm::Triple::IOS:
    305   case llvm::Triple::TvOS:
    306     // Darwin defaults to "softfp" for v6 and v7.
    307     if (Triple.isWatchABI())
    308       return FloatABI::Hard;
    309     else
    310       return (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
    311 
    312   case llvm::Triple::WatchOS:
    313     return FloatABI::Hard;
    314 
    315   // FIXME: this is invalid for WindowsCE
    316   case llvm::Triple::Win32:
    317     return FloatABI::Hard;
    318 
    319   case llvm::Triple::NetBSD:
    320     switch (Triple.getEnvironment()) {
    321     case llvm::Triple::EABIHF:
    322     case llvm::Triple::GNUEABIHF:
    323       return FloatABI::Hard;
    324     default:
    325       return FloatABI::Soft;
    326     }
    327     break;
    328 
    329   case llvm::Triple::FreeBSD:
    330     switch (Triple.getEnvironment()) {
    331     case llvm::Triple::GNUEABIHF:
    332       return FloatABI::Hard;
    333     default:
    334       // FreeBSD defaults to soft float
    335       return FloatABI::Soft;
    336     }
    337     break;
    338 
    339   case llvm::Triple::OpenBSD:
    340     return FloatABI::SoftFP;
    341 
    342   default:
    343     switch (Triple.getEnvironment()) {
    344     case llvm::Triple::GNUEABIHF:
    345     case llvm::Triple::MuslEABIHF:
    346     case llvm::Triple::EABIHF:
    347       return FloatABI::Hard;
    348     case llvm::Triple::GNUEABI:
    349     case llvm::Triple::MuslEABI:
    350     case llvm::Triple::EABI:
    351       // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
    352       return FloatABI::SoftFP;
    353     case llvm::Triple::Android:
    354       return (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft;
    355     default:
    356       return FloatABI::Invalid;
    357     }
    358   }
    359   return FloatABI::Invalid;
    360 }
    361 
    362 // Select the float ABI as determined by -msoft-float, -mhard-float, and
    363 // -mfloat-abi=.
    364 arm::FloatABI arm::getARMFloatABI(const Driver &D, const llvm::Triple &Triple,
    365                                   const ArgList &Args) {
    366   arm::FloatABI ABI = FloatABI::Invalid;
    367   if (Arg *A =
    368           Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
    369                           options::OPT_mfloat_abi_EQ)) {
    370     if (A->getOption().matches(options::OPT_msoft_float)) {
    371       ABI = FloatABI::Soft;
    372     } else if (A->getOption().matches(options::OPT_mhard_float)) {
    373       ABI = FloatABI::Hard;
    374     } else {
    375       ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
    376                 .Case("soft", FloatABI::Soft)
    377                 .Case("softfp", FloatABI::SoftFP)
    378                 .Case("hard", FloatABI::Hard)
    379                 .Default(FloatABI::Invalid);
    380       if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
    381         D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
    382         ABI = FloatABI::Soft;
    383       }
    384     }
    385   }
    386 
    387   // If unspecified, choose the default based on the platform.
    388   if (ABI == FloatABI::Invalid)
    389     ABI = arm::getDefaultFloatABI(Triple);
    390 
    391   if (ABI == FloatABI::Invalid) {
    392     // Assume "soft", but warn the user we are guessing.
    393     if (Triple.isOSBinFormatMachO() &&
    394         Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
    395       ABI = FloatABI::Hard;
    396     else
    397       ABI = FloatABI::Soft;
    398 
    399     if (Triple.getOS() != llvm::Triple::UnknownOS ||
    400         !Triple.isOSBinFormatMachO())
    401       D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
    402   }
    403 
    404   assert(ABI != FloatABI::Invalid && "must select an ABI");
    405   return ABI;
    406 }
    407 
    408 static bool hasIntegerMVE(const std::vector<StringRef> &F) {
    409   auto MVE = llvm::find(llvm::reverse(F), "+mve");
    410   auto NoMVE = llvm::find(llvm::reverse(F), "-mve");
    411   return MVE != F.rend() &&
    412          (NoMVE == F.rend() || std::distance(MVE, NoMVE) > 0);
    413 }
    414 
    415 void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
    416                                const ArgList &Args, ArgStringList &CmdArgs,
    417                                std::vector<StringRef> &Features, bool ForAS) {
    418   bool KernelOrKext =
    419       Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
    420   arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args);
    421   arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args);
    422   llvm::Optional<std::pair<const Arg *, StringRef>> WaCPU, WaFPU, WaHDiv,
    423       WaArch;
    424 
    425   // This vector will accumulate features from the architecture
    426   // extension suffixes on -mcpu and -march (e.g. the 'bar' in
    427   // -mcpu=foo+bar). We want to apply those after the features derived
    428   // from the FPU, in case -mfpu generates a negative feature which
    429   // the +bar is supposed to override.
    430   std::vector<StringRef> ExtensionFeatures;
    431 
    432   if (!ForAS) {
    433     // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
    434     // yet (it uses the -mfloat-abi and -msoft-float options), and it is
    435     // stripped out by the ARM target. We should probably pass this a new
    436     // -target-option, which is handled by the -cc1/-cc1as invocation.
    437     //
    438     // FIXME2:  For consistency, it would be ideal if we set up the target
    439     // machine state the same when using the frontend or the assembler. We don't
    440     // currently do that for the assembler, we pass the options directly to the
    441     // backend and never even instantiate the frontend TargetInfo. If we did,
    442     // and used its handleTargetFeatures hook, then we could ensure the
    443     // assembler and the frontend behave the same.
    444 
    445     // Use software floating point operations?
    446     if (ABI == arm::FloatABI::Soft)
    447       Features.push_back("+soft-float");
    448 
    449     // Use software floating point argument passing?
    450     if (ABI != arm::FloatABI::Hard)
    451       Features.push_back("+soft-float-abi");
    452   } else {
    453     // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
    454     // to the assembler correctly.
    455     for (const Arg *A :
    456          Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
    457       // We use getValues here because you can have many options per -Wa
    458       // We will keep the last one we find for each of these
    459       for (StringRef Value : A->getValues()) {
    460         if (Value.startswith("-mfpu=")) {
    461           WaFPU = std::make_pair(A, Value.substr(6));
    462         } else if (Value.startswith("-mcpu=")) {
    463           WaCPU = std::make_pair(A, Value.substr(6));
    464         } else if (Value.startswith("-mhwdiv=")) {
    465           WaHDiv = std::make_pair(A, Value.substr(8));
    466         } else if (Value.startswith("-march=")) {
    467           WaArch = std::make_pair(A, Value.substr(7));
    468         }
    469       }
    470     }
    471   }
    472 
    473   if (ThreadPointer == arm::ReadTPMode::Cp15)
    474     Features.push_back("+read-tp-hard");
    475 
    476   const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
    477   const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
    478   StringRef ArchName;
    479   StringRef CPUName;
    480   unsigned ArchArgFPUID = llvm::ARM::FK_INVALID;
    481   unsigned CPUArgFPUID = llvm::ARM::FK_INVALID;
    482 
    483   // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
    484   if (WaCPU) {
    485     if (CPUArg)
    486       D.Diag(clang::diag::warn_drv_unused_argument)
    487           << CPUArg->getAsString(Args);
    488     CPUName = WaCPU->second;
    489     CPUArg = WaCPU->first;
    490   } else if (CPUArg)
    491     CPUName = CPUArg->getValue();
    492 
    493   // Check -march. ClangAs gives preference to -Wa,-march=.
    494   if (WaArch) {
    495     if (ArchArg)
    496       D.Diag(clang::diag::warn_drv_unused_argument)
    497           << ArchArg->getAsString(Args);
    498     ArchName = WaArch->second;
    499     // This will set any features after the base architecture.
    500     checkARMArchName(D, WaArch->first, Args, ArchName, CPUName,
    501                      ExtensionFeatures, Triple, ArchArgFPUID);
    502     // The base architecture was handled in ToolChain::ComputeLLVMTriple because
    503     // triple is read only by this point.
    504   } else if (ArchArg) {
    505     ArchName = ArchArg->getValue();
    506     checkARMArchName(D, ArchArg, Args, ArchName, CPUName, ExtensionFeatures,
    507                      Triple, ArchArgFPUID);
    508   }
    509 
    510   // Add CPU features for generic CPUs
    511   if (CPUName == "native") {
    512     llvm::StringMap<bool> HostFeatures;
    513     if (llvm::sys::getHostCPUFeatures(HostFeatures))
    514       for (auto &F : HostFeatures)
    515         Features.push_back(
    516             Args.MakeArgString((F.second ? "+" : "-") + F.first()));
    517   } else if (!CPUName.empty()) {
    518     // This sets the default features for the specified CPU. We certainly don't
    519     // want to override the features that have been explicitly specified on the
    520     // command line. Therefore, process them directly instead of appending them
    521     // at the end later.
    522     DecodeARMFeaturesFromCPU(D, CPUName, Features);
    523   }
    524 
    525   if (CPUArg)
    526     checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, ExtensionFeatures,
    527                     Triple, CPUArgFPUID);
    528   // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
    529   unsigned FPUID = llvm::ARM::FK_INVALID;
    530   const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
    531   if (WaFPU) {
    532     if (FPUArg)
    533       D.Diag(clang::diag::warn_drv_unused_argument)
    534           << FPUArg->getAsString(Args);
    535     (void)getARMFPUFeatures(D, WaFPU->first, Args, WaFPU->second, Features);
    536   } else if (FPUArg) {
    537     FPUID = getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
    538   } else if (Triple.isAndroid() && getARMSubArchVersionNumber(Triple) >= 7) {
    539     const char *AndroidFPU = "neon";
    540     FPUID = llvm::ARM::parseFPU(AndroidFPU);
    541     if (!llvm::ARM::getFPUFeatures(FPUID, Features))
    542       D.Diag(clang::diag::err_drv_clang_unsupported)
    543           << std::string("-mfpu=") + AndroidFPU;
    544   } else {
    545     if (!ForAS) {
    546       std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
    547       llvm::ARM::ArchKind ArchKind =
    548           arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
    549       FPUID = llvm::ARM::getDefaultFPU(CPU, ArchKind);
    550       (void)llvm::ARM::getFPUFeatures(FPUID, Features);
    551     }
    552   }
    553 
    554   // Now we've finished accumulating features from arch, cpu and fpu,
    555   // we can append the ones for architecture extensions that we
    556   // collected separately.
    557   Features.insert(std::end(Features),
    558                   std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
    559 
    560   // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
    561   const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
    562   if (WaHDiv) {
    563     if (HDivArg)
    564       D.Diag(clang::diag::warn_drv_unused_argument)
    565           << HDivArg->getAsString(Args);
    566     getARMHWDivFeatures(D, WaHDiv->first, Args, WaHDiv->second, Features);
    567   } else if (HDivArg)
    568     getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
    569 
    570   // Handle (arch-dependent) fp16fml/fullfp16 relationship.
    571   // Must happen before any features are disabled due to soft-float.
    572   // FIXME: this fp16fml option handling will be reimplemented after the
    573   // TargetParser rewrite.
    574   const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16");
    575   const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml");
    576   if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
    577     const auto ItRFullFP16  = std::find(Features.rbegin(), Features.rend(), "+fullfp16");
    578     if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
    579       // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
    580       // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
    581       if (std::find(Features.rbegin(), ItRFullFP16, "-fp16fml") == ItRFullFP16)
    582         Features.push_back("+fp16fml");
    583     }
    584     else
    585       goto fp16_fml_fallthrough;
    586   }
    587   else {
    588 fp16_fml_fallthrough:
    589     // In both of these cases, putting the 'other' feature on the end of the vector will
    590     // result in the same effect as placing it immediately after the current feature.
    591     if (ItRNoFullFP16 < ItRFP16FML)
    592       Features.push_back("-fp16fml");
    593     else if (ItRNoFullFP16 > ItRFP16FML)
    594       Features.push_back("+fullfp16");
    595   }
    596 
    597   // Setting -msoft-float/-mfloat-abi=soft, -mfpu=none, or adding +nofp to
    598   // -march/-mcpu effectively disables the FPU (GCC ignores the -mfpu options in
    599   // this case). Note that the ABI can also be set implicitly by the target
    600   // selected.
    601   if (ABI == arm::FloatABI::Soft) {
    602     llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
    603 
    604     // Disable all features relating to hardware FP, not already disabled by the
    605     // above call.
    606     Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-bf16", "-mve",
    607                                      "-mve.fp", "-fpregs"});
    608   } else if (FPUID == llvm::ARM::FK_NONE ||
    609              ArchArgFPUID == llvm::ARM::FK_NONE ||
    610              CPUArgFPUID == llvm::ARM::FK_NONE) {
    611     // -mfpu=none, -march=armvX+nofp or -mcpu=X+nofp is *very* similar to
    612     // -mfloat-abi=soft, only that it should not disable MVE-I. They disable the
    613     // FPU, but not the FPU registers, thus MVE-I, which depends only on the
    614     // latter, is still supported.
    615     Features.insert(Features.end(),
    616                     {"-dotprod", "-fp16fml", "-bf16", "-mve.fp"});
    617     if (!hasIntegerMVE(Features))
    618       Features.emplace_back("-fpregs");
    619   }
    620 
    621   // En/disable crc code generation.
    622   if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
    623     if (A->getOption().matches(options::OPT_mcrc))
    624       Features.push_back("+crc");
    625     else
    626       Features.push_back("-crc");
    627   }
    628 
    629   // For Arch >= ARMv8.0 && A or R profile:  crypto = sha2 + aes
    630   // Rather than replace within the feature vector, determine whether each
    631   // algorithm is enabled and append this to the end of the vector.
    632   // The algorithms can be controlled by their specific feature or the crypto
    633   // feature, so their status can be determined by the last occurance of
    634   // either in the vector. This allows one to supercede the other.
    635   // e.g. +crypto+noaes in -march/-mcpu should enable sha2, but not aes
    636   // FIXME: this needs reimplementation after the TargetParser rewrite
    637   bool HasSHA2 = false;
    638   bool HasAES = false;
    639   const auto ItCrypto =
    640       llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
    641         return F.contains("crypto");
    642       });
    643   const auto ItSHA2 =
    644       llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
    645         return F.contains("crypto") || F.contains("sha2");
    646       });
    647   const auto ItAES =
    648       llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
    649         return F.contains("crypto") || F.contains("aes");
    650       });
    651   const bool FoundSHA2 = ItSHA2 != Features.rend();
    652   const bool FoundAES = ItAES != Features.rend();
    653   if (FoundSHA2)
    654     HasSHA2 = ItSHA2->take_front() == "+";
    655   if (FoundAES)
    656     HasAES = ItAES->take_front() == "+";
    657   if (ItCrypto != Features.rend()) {
    658     if (HasSHA2 && HasAES)
    659       Features.push_back("+crypto");
    660     else
    661       Features.push_back("-crypto");
    662     if (HasSHA2)
    663       Features.push_back("+sha2");
    664     else
    665       Features.push_back("-sha2");
    666     if (HasAES)
    667       Features.push_back("+aes");
    668     else
    669       Features.push_back("-aes");
    670   }
    671 
    672   if (HasSHA2 || HasAES) {
    673     StringRef ArchSuffix = arm::getLLVMArchSuffixForARM(
    674         arm::getARMTargetCPU(CPUName, ArchName, Triple), ArchName, Triple);
    675     llvm::ARM::ProfileKind ArchProfile =
    676         llvm::ARM::parseArchProfile(ArchSuffix);
    677     if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) &&
    678           (ArchProfile == llvm::ARM::ProfileKind::A ||
    679            ArchProfile == llvm::ARM::ProfileKind::R))) {
    680       if (HasSHA2)
    681         D.Diag(clang::diag::warn_target_unsupported_extension)
    682             << "sha2"
    683             << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
    684       if (HasAES)
    685         D.Diag(clang::diag::warn_target_unsupported_extension)
    686             << "aes"
    687             << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
    688       // With -fno-integrated-as -mfpu=crypto-neon-fp-armv8 some assemblers such
    689       // as the GNU assembler will permit the use of crypto instructions as the
    690       // fpu will override the architecture. We keep the crypto feature in this
    691       // case to preserve compatibility. In all other cases we remove the crypto
    692       // feature.
    693       if (!Args.hasArg(options::OPT_fno_integrated_as)) {
    694         Features.push_back("-sha2");
    695         Features.push_back("-aes");
    696       }
    697     }
    698   }
    699 
    700   // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later.
    701   if (Args.getLastArg(options::OPT_mcmse))
    702     Features.push_back("+8msecext");
    703 
    704   // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
    705   // neither options are specified, see if we are compiling for kernel/kext and
    706   // decide whether to pass "+long-calls" based on the OS and its version.
    707   if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
    708                                options::OPT_mno_long_calls)) {
    709     if (A->getOption().matches(options::OPT_mlong_calls))
    710       Features.push_back("+long-calls");
    711   } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
    712              !Triple.isWatchOS()) {
    713       Features.push_back("+long-calls");
    714   }
    715 
    716   // Generate execute-only output (no data access to code sections).
    717   // This only makes sense for the compiler, not for the assembler.
    718   if (!ForAS) {
    719     // Supported only on ARMv6T2 and ARMv7 and above.
    720     // Cannot be combined with -mno-movt or -mlong-calls
    721     if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
    722       if (A->getOption().matches(options::OPT_mexecute_only)) {
    723         if (getARMSubArchVersionNumber(Triple) < 7 &&
    724             llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2)
    725               D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
    726         else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
    727           D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
    728         // Long calls create constant pool entries and have not yet been fixed up
    729         // to play nicely with execute-only. Hence, they cannot be used in
    730         // execute-only code for now
    731         else if (Arg *B = Args.getLastArg(options::OPT_mlong_calls, options::OPT_mno_long_calls)) {
    732           if (B->getOption().matches(options::OPT_mlong_calls))
    733             D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
    734         }
    735         Features.push_back("+execute-only");
    736       }
    737     }
    738   }
    739 
    740   // Kernel code has more strict alignment requirements.
    741   if (KernelOrKext)
    742     Features.push_back("+strict-align");
    743   else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
    744                                     options::OPT_munaligned_access)) {
    745     if (A->getOption().matches(options::OPT_munaligned_access)) {
    746       // No v6M core supports unaligned memory access (v6M ARM ARM A3.2).
    747       if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
    748         D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
    749       // v8M Baseline follows on from v6M, so doesn't support unaligned memory
    750       // access either.
    751       else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
    752         D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base";
    753     } else
    754       Features.push_back("+strict-align");
    755   } else {
    756     // Assume pre-ARMv6 doesn't support unaligned accesses.
    757     //
    758     // ARMv6 may or may not support unaligned accesses depending on the
    759     // SCTLR.U bit, which is architecture-specific. We assume ARMv6
    760     // Darwin and NetBSD targets support unaligned accesses, and others don't.
    761     //
    762     // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
    763     // which raises an alignment fault on unaligned accesses. Linux
    764     // defaults this bit to 0 and handles it as a system-wide (not
    765     // per-process) setting. It is therefore safe to assume that ARMv7+
    766     // Linux targets support unaligned accesses. The same goes for NaCl.
    767     //
    768     // The above behavior is consistent with GCC.
    769     int VersionNum = getARMSubArchVersionNumber(Triple);
    770     if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
    771       if (VersionNum < 6 ||
    772           Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
    773         Features.push_back("+strict-align");
    774     } else if (Triple.isOSLinux() || Triple.isOSNaCl()) {
    775       if (VersionNum < 7)
    776         Features.push_back("+strict-align");
    777     } else
    778       Features.push_back("+strict-align");
    779   }
    780 
    781   // llvm does not support reserving registers in general. There is support
    782   // for reserving r9 on ARM though (defined as a platform-specific register
    783   // in ARM EABI).
    784   if (Args.hasArg(options::OPT_ffixed_r9))
    785     Features.push_back("+reserve-r9");
    786 
    787   // The kext linker doesn't know how to deal with movw/movt.
    788   if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
    789     Features.push_back("+no-movt");
    790 
    791   if (Args.hasArg(options::OPT_mno_neg_immediates))
    792     Features.push_back("+no-neg-immediates");
    793 
    794   // Enable/disable straight line speculation hardening.
    795   if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
    796     StringRef Scope = A->getValue();
    797     bool EnableRetBr = false;
    798     bool EnableBlr = false;
    799     bool DisableComdat = false;
    800     if (Scope != "none") {
    801       SmallVector<StringRef, 4> Opts;
    802       Scope.split(Opts, ",");
    803       for (auto Opt : Opts) {
    804         Opt = Opt.trim();
    805         if (Opt == "all") {
    806           EnableBlr = true;
    807           EnableRetBr = true;
    808           continue;
    809         }
    810         if (Opt == "retbr") {
    811           EnableRetBr = true;
    812           continue;
    813         }
    814         if (Opt == "blr") {
    815           EnableBlr = true;
    816           continue;
    817         }
    818         if (Opt == "comdat") {
    819           DisableComdat = false;
    820           continue;
    821         }
    822         if (Opt == "nocomdat") {
    823           DisableComdat = true;
    824           continue;
    825         }
    826         D.Diag(diag::err_invalid_sls_hardening)
    827             << Scope << A->getAsString(Args);
    828         break;
    829       }
    830     }
    831 
    832     if (EnableRetBr || EnableBlr)
    833       if (!(isARMAProfile(Triple) && getARMSubArchVersionNumber(Triple) >= 7))
    834         D.Diag(diag::err_sls_hardening_arm_not_supported)
    835             << Scope << A->getAsString(Args);
    836 
    837     if (EnableRetBr)
    838       Features.push_back("+harden-sls-retbr");
    839     if (EnableBlr)
    840       Features.push_back("+harden-sls-blr");
    841     if (DisableComdat) {
    842       Features.push_back("+harden-sls-nocomdat");
    843     }
    844   }
    845 
    846 }
    847 
    848 const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
    849   std::string MArch;
    850   if (!Arch.empty())
    851     MArch = std::string(Arch);
    852   else
    853     MArch = std::string(Triple.getArchName());
    854   MArch = StringRef(MArch).split("+").first.lower();
    855 
    856   // Handle -march=native.
    857   if (MArch == "native") {
    858     std::string CPU = std::string(llvm::sys::getHostCPUName());
    859     if (CPU != "generic") {
    860       // Translate the native cpu into the architecture suffix for that CPU.
    861       StringRef Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
    862       // If there is no valid architecture suffix for this CPU we don't know how
    863       // to handle it, so return no architecture.
    864       if (Suffix.empty())
    865         MArch = "";
    866       else
    867         MArch = std::string("arm") + Suffix.str();
    868     }
    869   }
    870 
    871   return MArch;
    872 }
    873 
    874 /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
    875 StringRef arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) {
    876   std::string MArch = getARMArch(Arch, Triple);
    877   // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
    878   // here means an -march=native that we can't handle, so instead return no CPU.
    879   if (MArch.empty())
    880     return StringRef();
    881 
    882   // We need to return an empty string here on invalid MArch values as the
    883   // various places that call this function can't cope with a null result.
    884   return Triple.getARMCPUForArch(MArch);
    885 }
    886 
    887 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
    888 std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
    889                                  const llvm::Triple &Triple) {
    890   // FIXME: Warn on inconsistent use of -mcpu and -march.
    891   // If we have -mcpu=, use that.
    892   if (!CPU.empty()) {
    893     std::string MCPU = StringRef(CPU).split("+").first.lower();
    894     // Handle -mcpu=native.
    895     if (MCPU == "native")
    896       return std::string(llvm::sys::getHostCPUName());
    897     else
    898       return MCPU;
    899   }
    900 
    901   return std::string(getARMCPUForMArch(Arch, Triple));
    902 }
    903 
    904 /// getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a
    905 /// particular CPU (or Arch, if CPU is generic). This is needed to
    906 /// pass to functions like llvm::ARM::getDefaultFPU which need an
    907 /// ArchKind as well as a CPU name.
    908 llvm::ARM::ArchKind arm::getLLVMArchKindForARM(StringRef CPU, StringRef Arch,
    909                                                const llvm::Triple &Triple) {
    910   llvm::ARM::ArchKind ArchKind;
    911   if (CPU == "generic" || CPU.empty()) {
    912     std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
    913     ArchKind = llvm::ARM::parseArch(ARMArch);
    914     if (ArchKind == llvm::ARM::ArchKind::INVALID)
    915       // In case of generic Arch, i.e. "arm",
    916       // extract arch from default cpu of the Triple
    917       ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
    918   } else {
    919     // FIXME: horrible hack to get around the fact that Cortex-A7 is only an
    920     // armv7k triple if it's actually been specified via "-arch armv7k".
    921     ArchKind = (Arch == "armv7k" || Arch == "thumbv7k")
    922                           ? llvm::ARM::ArchKind::ARMV7K
    923                           : llvm::ARM::parseCPUArch(CPU);
    924   }
    925   return ArchKind;
    926 }
    927 
    928 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
    929 /// CPU  (or Arch, if CPU is generic).
    930 // FIXME: This is redundant with -mcpu, why does LLVM use this.
    931 StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
    932                                        const llvm::Triple &Triple) {
    933   llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple);
    934   if (ArchKind == llvm::ARM::ArchKind::INVALID)
    935     return "";
    936   return llvm::ARM::getSubArch(ArchKind);
    937 }
    938 
    939 void arm::appendBE8LinkFlag(const ArgList &Args, ArgStringList &CmdArgs,
    940                             const llvm::Triple &Triple) {
    941   if (Args.hasArg(options::OPT_r))
    942     return;
    943 
    944   // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
    945   // to generate BE-8 executables.
    946   if (arm::getARMSubArchVersionNumber(Triple) >= 7 || arm::isARMMProfile(Triple))
    947     CmdArgs.push_back("--be8");
    948 }
    949