spetrovic updated this revision to Diff 109088.

https://reviews.llvm.org/D34878

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  include/clang/Driver/CC1Options.td
  include/clang/Driver/Options.td
  lib/Driver/ToolChains/Arch/ARM.cpp
  lib/Driver/ToolChains/Arch/ARM.h
  lib/Driver/ToolChains/Clang.cpp
  test/Driver/clang-translation.c

Index: test/Driver/clang-translation.c
===================================================================
--- test/Driver/clang-translation.c
+++ test/Driver/clang-translation.c
@@ -75,6 +75,12 @@
 // ARMV5E: "-cc1"
 // ARMV5E: "-target-cpu" "arm1022e"
 
+// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER %s
+// ARMv7_THREAD_POINTER: "-target-feature" "+read-tp-hard"
+// ARMv7_THREAD_POINTER: "-mtp" "cp15"
+// ARMv7_THREAD_POINTER-NOT: "mtp" "soft"
+
 // RUN: %clang -target powerpc64-unknown-linux-gnu \
 // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s
 // PPCG5: clang
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -1345,6 +1345,17 @@
     CmdArgs.push_back("hard");
   }
 
+  arm::ReadTPMode ThreadPointer = arm::getReadTPMode(getToolChain(), Args);
+  if (ThreadPointer == arm::ReadTPMode::Cp15) {
+    CmdArgs.push_back("-mtp");
+    CmdArgs.push_back("cp15");
+  } else {
+    assert(ThreadPointer == arm::ReadTPMode::Soft &&
+           "Invalid mode for reading thread pointer");
+    CmdArgs.push_back("-mtp");
+    CmdArgs.push_back("soft");
+  }
+
   // Forward the -mglobal-merge option for explicit control over the pass.
   if (Arg *A = Args.getLastArg(options::OPT_mglobal_merge,
                                options::OPT_mno_global_merge)) {
Index: lib/Driver/ToolChains/Arch/ARM.h
===================================================================
--- lib/Driver/ToolChains/Arch/ARM.h
+++ lib/Driver/ToolChains/Arch/ARM.h
@@ -32,14 +32,21 @@
 void appendEBLinkFlags(const llvm::opt::ArgList &Args,
                        llvm::opt::ArgStringList &CmdArgs,
                        const llvm::Triple &Triple);
+enum class ReadTPMode {
+  Invalid,
+  Soft,
+  Cp15,
+};
+
 enum class FloatABI {
   Invalid,
   Soft,
   SoftFP,
   Hard,
 };
 
 FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args);
+ReadTPMode getReadTPMode(const ToolChain &TC, const llvm::opt::ArgList &Args);
 
 bool useAAPCSForMachO(const llvm::Triple &T);
 void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args,
Index: lib/Driver/ToolChains/Arch/ARM.cpp
===================================================================
--- lib/Driver/ToolChains/Arch/ARM.cpp
+++ lib/Driver/ToolChains/Arch/ARM.cpp
@@ -122,6 +122,27 @@
          T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
 }
 
+// Select mode for reading thread pointer (-mtp=soft/cp15).
+arm::ReadTPMode arm::getReadTPMode(const ToolChain &TC, const ArgList &Args) {
+  const Driver &D = TC.getDriver();
+  arm::ReadTPMode ThreadPointer = ReadTPMode::Invalid;
+  if (Arg *A =
+          Args.getLastArg(options::OPT_mtp_mode_EQ)) {
+    ThreadPointer = llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
+                        .Case("cp15", ReadTPMode::Cp15)
+                        .Case("soft", ReadTPMode::Soft)
+                        .Default(ReadTPMode::Invalid);
+    if (ThreadPointer == ReadTPMode::Invalid &&
+        !StringRef(A->getValue()).empty()) {
+      D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
+      ThreadPointer = ReadTPMode::Soft;
+    }
+  }
+  if (ThreadPointer == ReadTPMode::Invalid)
+    ThreadPointer = ReadTPMode::Soft;
+  return ThreadPointer;
+}
+
 // Select the float ABI as determined by -msoft-float, -mhard-float, and
 // -mfloat-abi=.
 arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
@@ -253,6 +274,7 @@
   bool KernelOrKext =
       Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
   arm::FloatABI ABI = arm::getARMFloatABI(TC, Args);
+  arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args);
   const Arg *WaCPU = nullptr, *WaFPU = nullptr;
   const Arg *WaHDiv = nullptr, *WaArch = nullptr;
 
@@ -294,6 +316,10 @@
     }
   }
 
+
+  if (ThreadPointer == arm::ReadTPMode::Cp15)
+    Features.push_back("+read-tp-hard");
+
   // Check -march. ClangAs gives preference to -Wa,-march=.
   const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
   StringRef ArchName;
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1661,6 +1661,8 @@
   HelpText<"Disallow generation of data access to code sections (ARM only)">;
 def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>,
   HelpText<"Allow generation of data access to code sections (ARM only)">;
+def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft, cp15">,
+  HelpText<"Read thread pointer from coprocessor register (ARM only)">;
 def mpure_code : Flag<["-"], "mpure-code">, Alias<mexecute_only>; // Alias for GCC compatibility
 def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>;
 def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -245,6 +245,8 @@
            "precision">;
 def mfloat_abi : Separate<["-"], "mfloat-abi">,
   HelpText<"The float ABI to use">;
+def mtp : Separate<["-"], "mtp">,
+  HelpText<"Mode for reading thread pointer">;
 def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">,
   HelpText<"Limit float precision to the given value">;
 def split_stacks : Flag<["-"], "split-stacks">,
Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -97,6 +97,8 @@
   "failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">;
 def err_drv_invalid_mfloat_abi : Error<
   "invalid float ABI '%0'">;
+def err_drv_invalid_mtp : Error<
+  "invalid thread pointer reading mode '%0'">;
 def err_drv_invalid_libcxx_deployment : Error<
   "invalid deployment target for -stdlib=libc++ (requires %0 or later)">;
 def err_drv_invalid_argument_to_fdebug_prefix_map : Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to