Hi rengolin,

Using the target cpu to determine some behaviour is sprinkled in several places 
in the driver, but in almost all the information that is needed can be found in 
the triple. Restructure things so that the triple is used, and the cpu is only 
used if the exact cpu name is needed.

Also add a check that the -mcpu argument is valid, and correct the -march 
argument checking so that it handles -march=native correctly. I would have 
liked to move these checks into the computation of the triple, but the triple 
is calculated several times in several places and that would lead to multiple 
error messages for the same thing.

REPOSITORY
  rL LLVM

http://reviews.llvm.org/D9879

Files:
  lib/Driver/Tools.cpp
  test/Driver/arm-cortex-cpus.c

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -617,6 +617,42 @@
   }
 }
 
+static int getARMSubArchVersionNumber(const llvm::Triple &Triple) {
+  switch (Triple.getSubArch()) {
+  case llvm::Triple::ARMSubArch_v8_1a:
+  case llvm::Triple::ARMSubArch_v8:
+    return 8;
+  case llvm::Triple::ARMSubArch_v7:
+  case llvm::Triple::ARMSubArch_v7em:
+  case llvm::Triple::ARMSubArch_v7m:
+  case llvm::Triple::ARMSubArch_v7s:
+    return 7;
+  case llvm::Triple::ARMSubArch_v6:
+  case llvm::Triple::ARMSubArch_v6m:
+  case llvm::Triple::ARMSubArch_v6k:
+  case llvm::Triple::ARMSubArch_v6t2:
+    return 6;
+  case llvm::Triple::ARMSubArch_v5:
+  case llvm::Triple::ARMSubArch_v5te:
+    return 5;
+  case llvm::Triple::ARMSubArch_v4t:
+    return 4;
+  default:
+    return 0;
+  }
+}
+
+static bool isARMMProfile(const llvm::Triple &Triple) {
+  switch (Triple.getSubArch()) {
+  case llvm::Triple::ARMSubArch_v7em:
+  case llvm::Triple::ARMSubArch_v7m:
+  case llvm::Triple::ARMSubArch_v6m:
+    return true;
+  default:
+    return false;
+  }
+}
+
 // Select the float ABI as determined by -msoft-float, -mhard-float, and
 // -mfloat-abi=.
 StringRef tools::arm::getARMFloatABI(const Driver &D, const ArgList &Args,
@@ -647,12 +683,8 @@
     case llvm::Triple::IOS: {
       // Darwin defaults to "softfp" for v6 and v7.
       //
-      // FIXME: Factor out an ARM class so we can cache the arch somewhere.
-      std::string ArchName =
-        arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple),
-                                     arm::getARMArch(Args, Triple));
-      if (StringRef(ArchName).startswith("v6") ||
-          StringRef(ArchName).startswith("v7"))
+      if (getARMSubArchVersionNumber(Triple) == 6 ||
+          getARMSubArchVersionNumber(Triple) == 7)
         FloatABI = "softfp";
       else
         FloatABI = "soft";
@@ -692,10 +724,7 @@
         FloatABI = "softfp";
         break;
       case llvm::Triple::Android: {
-        std::string ArchName =
-          arm::getLLVMArchSuffixForARM(arm::getARMTargetCPU(Args, Triple),
-                                       arm::getARMArch(Args, Triple));
-        if (StringRef(ArchName).startswith("v7"))
+        if (getARMSubArchVersionNumber(Triple) == 7)
           FloatABI = "softfp";
         else
           FloatABI = "soft";
@@ -748,13 +777,23 @@
   if (const Arg *A = Args.getLastArg(options::OPT_mhwdiv_EQ))
     getARMHWDivFeatures(D, A, Args, Features);
 
-  // -march is handled in getARMCPUForMarch by translating it into a CPU name,
+  // -march is handled in getARMCPUForMArch by translating it into a CPU name,
   // but it needs to return an empty string on invalid arguments. We therefore
   // check and give an error here if the -march is invalid.
   if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
-    if (!Triple.getARMCPUForArch(A->getValue()))
+    if (strcmp(arm::getARMCPUForMArch(Args, Triple),"") == 0)
       D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
 
+  // We do a similar thing with -mcpu, but here things are complicated because
+  // the only function we have to check if a cpu is valid is
+  // getLLVMArchSuffixForARM which also needs an architecture.
+  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) {
+    StringRef CPU = arm::getARMTargetCPU(Args, Triple);
+    StringRef Arch = arm::getARMArch(Args, Triple);
+    if (strcmp(arm::getLLVMArchSuffixForARM(CPU, Arch), "") == 0)
+      D.Diag(diag::err_drv_clang_unsupported) << A->getAsString(Args);
+  }
+
   // Setting -msoft-float effectively disables NEON because of the GCC
   // implementation, although the same isn't true of VFP or VFP3.
   if (FloatABI == "soft") {
@@ -783,7 +822,6 @@
   // Get the effective triple, which takes into account the deployment target.
   std::string TripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
   llvm::Triple Triple(TripleStr);
-  std::string CPUName = arm::getARMTargetCPU(Args, Triple);
 
   // Select the ABI to use.
   //
@@ -797,7 +835,7 @@
     // the frontend matches that.
     if (Triple.getEnvironment() == llvm::Triple::EABI ||
         Triple.getOS() == llvm::Triple::UnknownOS ||
-        StringRef(CPUName).startswith("cortex-m")) {
+        isARMMProfile(Triple)) {
       ABIName = "aapcs";
     } else {
       ABIName = "apcs-gnu";
@@ -3209,9 +3247,7 @@
   }
 
   // Add the target cpu
-  std::string ETripleStr = getToolChain().ComputeEffectiveClangTriple(Args);
-  llvm::Triple ETriple(ETripleStr);
-  std::string CPU = getCPUName(Args, ETriple);
+  std::string CPU = getCPUName(Args, Triple);
   if (!CPU.empty()) {
     CmdArgs.push_back("-target-cpu");
     CmdArgs.push_back(Args.MakeArgString(CPU));
@@ -3223,7 +3259,7 @@
   }
 
   // Add the target features
-  getTargetFeatures(D, ETriple, Args, CmdArgs, false);
+  getTargetFeatures(D, Triple, Args, CmdArgs, false);
 
   // Add target specific flags.
   switch(getToolChain().getArch()) {
@@ -5105,7 +5141,7 @@
   CmdArgs.push_back(Clang::getBaseInputName(Args, Input));
 
   // Add the target cpu
-  const llvm::Triple &Triple = getToolChain().getTriple();
+  const llvm::Triple Triple(TripleStr);
   std::string CPU = getCPUName(Args, Triple);
   if (!CPU.empty()) {
     CmdArgs.push_back("-target-cpu");
@@ -5645,6 +5681,10 @@
       // then chose the minimum cpu for that arch.
       MArch = std::string("arm") + 
         arm::getLLVMArchSuffixForARM(CPU, arm::getARMArch(Args, Triple));
+      // If there is no valid architecture suffix for this CPU then we don't
+      // know the correct minimum CPU, so don't return one.
+      if (MArch == "arm")
+        return "";
     }
   }
 
@@ -5690,7 +5730,8 @@
   }
 
   return llvm::StringSwitch<const char *>(CPU)
-    .Case("strongarm", "v4")
+    .Cases("arm8", "arm810", "4")
+    .Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "v4")
     .Cases("arm7tdmi", "arm7tdmi-s", "arm710t", "v4t")
     .Cases("arm720t", "arm9", "arm9tdmi", "v4t")
     .Cases("arm920", "arm920t", "arm922t", "v4t")
@@ -5720,15 +5761,10 @@
   if (Args.hasArg(options::OPT_r))
     return;
 
-  StringRef Suffix = getLLVMArchSuffixForARM(getARMCPUForMArch(Args, Triple), 
-                                             getARMArch(Args, Triple));
-  const char *LinkFlag = llvm::StringSwitch<const char *>(Suffix)
-    .Cases("v4", "v4t", "v5", "v5e", nullptr)
-    .Cases("v6", "v6k", "v6t2", nullptr)
-    .Default("--be8");
-
-  if (LinkFlag)
-    CmdArgs.push_back(LinkFlag);
+  // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
+  // to generate BE-8 executables.
+  if (getARMSubArchVersionNumber(Triple) >= 7 || isARMMProfile(Triple))
+    CmdArgs.push_back("--be8");
 }
 
 mips::NanEncoding mips::getSupportedNanEncoding(StringRef &CPU) {
@@ -7314,7 +7350,8 @@
     break;
   case llvm::Triple::armeb:
   case llvm::Triple::thumbeb:
-    arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple());
+    arm::appendEBLinkFlags(Args, CmdArgs,
+        llvm::Triple(getToolChain().ComputeEffectiveClangTriple(Args)));
     CmdArgs.push_back("-m");
     switch (getToolChain().getTriple().getEnvironment()) {
     case llvm::Triple::EABI:
@@ -7890,7 +7927,8 @@
 
   if (ToolChain.getArch() == llvm::Triple::armeb ||
       ToolChain.getArch() == llvm::Triple::thumbeb)
-    arm::appendEBLinkFlags(Args, CmdArgs, getToolChain().getTriple());
+    arm::appendEBLinkFlags(Args, CmdArgs,
+        llvm::Triple(getToolChain().ComputeEffectiveClangTriple(Args)));
 
   for (const auto &Opt : ToolChain.ExtraOpts)
     CmdArgs.push_back(Opt.c_str());
Index: test/Driver/arm-cortex-cpus.c
===================================================================
--- test/Driver/arm-cortex-cpus.c
+++ test/Driver/arm-cortex-cpus.c
@@ -205,6 +205,10 @@
 // RUN: %clang -target arm---eabihf -march=armbogusv7 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BOGUS-HF %s
 // CHECK-BOGUS-HF: error: the clang compiler does not support '-march=armbogusv7' 
 
+// ================== Check that a bogus CPU gives an error
+// RUN: %clang -target arm -mcpu=bogus -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-BOGUS-CPU %s
+// CHECK-BOGUS-CPU: error: the clang compiler does not support '-mcpu=bogus' 
+
 // ================== Check default Architecture on each ARM11 CPU
 // RUN: %clang -target arm-linux-gnueabi -mcpu=arm1136j-s -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV6 %s
 // RUN: %clang -target arm-linux-gnueabi -mcpu=arm1136jf-s -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CPUV6 %s
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to