[clang] 10e4228 - [ARM,AArch64] Add a full set of -mtp= options.

Simon Tatham via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 15 01:27:56 PDT 2023


Author: Simon Tatham
Date: 2023-06-15T09:27:41+01:00
New Revision: 10e42281144ecca019764b554f3f0f709bba0f71

URL: https://github.com/llvm/llvm-project/commit/10e42281144ecca019764b554f3f0f709bba0f71
DIFF: https://github.com/llvm/llvm-project/commit/10e42281144ecca019764b554f3f0f709bba0f71.diff

LOG: [ARM,AArch64] Add a full set of -mtp= options.

AArch64 has five system registers intended to be useful as thread
pointers: one for each exception level which is RW at that level and
inaccessible to lower ones, and the special TPIDRRO_EL0 which is
readable but not writable at EL0. AArch32 has three, corresponding to
the AArch64 ones that aren't specific to EL2 or EL3.

Currently clang supports only a subset of these registers, and not
even a consistent subset between AArch64 and AArch32:

 - For AArch64, clang permits you to choose between the four TPIDR_ELn
   thread registers, but not the fifth one, TPIDRRO_EL0.

 - In AArch32, on the other hand, the //only// thread register you can
   choose (apart from 'none, use a function call') is TPIDRURO, which
   corresponds to (the bottom 32 bits of) AArch64's TPIDRRO_EL0.

So there is no thread register that you can currently use in both
targets!

For custom and bare-metal purposes, users might very reasonably want
to use any of these thread registers. There's no reason they shouldn't
all be supported as options, even if the default choices follow
existing practice on typical operating systems.

This commit extends the range of values acceptable to the `-mtp=`
clang option, so that you can specify any of these registers by (the
lower-case version of) their official names in the ArmARM:

 - For AArch64: tpidr_el0, tpidrro_el0, tpidr_el1, tpidr_el2, tpidr_el3
 - For AArch32: tpidrurw, tpidruro, tpidrprw

All existing values of the option are still supported and behave the
same as before. Defaults are also unchanged. No command line that
worked already should change behaviour as a result of this.

The new values for the `-mtp=` option have been agreed with Arm's gcc
developers (although I don't know whether they plan to implement them
in the near future).

Reviewed By: nickdesaulniers

Differential Revision: https://reviews.llvm.org/D152433

Added: 
    clang/test/Driver/aarch64-thread-pointer.c
    clang/test/Driver/arm-thread-pointer.c

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/Driver/ToolChains/Arch/AArch64.cpp
    clang/lib/Driver/ToolChains/Arch/ARM.cpp
    clang/lib/Driver/ToolChains/Arch/ARM.h
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/Driver/clang-translation.c
    llvm/lib/Target/AArch64/AArch64.td
    llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
    llvm/lib/Target/ARM/ARM.td
    llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
    llvm/lib/Target/ARM/ARMInstrInfo.td
    llvm/lib/Target/ARM/ARMInstrThumb2.td
    llvm/lib/Target/ARM/ARMPredicates.td
    llvm/lib/Target/ARM/ARMSubtarget.h
    llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll
    llvm/test/CodeGen/ARM/readtp.ll
    llvm/test/CodeGen/ARM/stack-guard-tls.ll
    llvm/test/CodeGen/ARM/thread_pointer.ll

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 750b6ab343852..06f02a05b7f13 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3595,8 +3595,10 @@ def mexecute_only : Flag<["-"], "mexecute-only">, Group<m_arm_Features_Group>,
 def mno_execute_only : Flag<["-"], "mno-execute-only">, Group<m_arm_Features_Group>,
   HelpText<"Allow generation of data access to code sections (ARM only)">;
 let Flags = [TargetSpecific] in {
-def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft,cp15,el0,el1,el2,el3">,
-  HelpText<"Thread pointer access method (AArch32/AArch64 only)">;
+def mtp_mode_EQ : Joined<["-"], "mtp=">, Group<m_arm_Features_Group>, Values<"soft,cp15,tpidrurw,tpidruro,tpidrprw,el0,el1,el2,el3,tpidr_el0,tpidr_el1,tpidr_el2,tpidr_el3,tpidrro_el0">,
+  HelpText<"Thread pointer access method. "
+           "For AArch32: 'soft' uses a function call, or 'tpidrurw', 'tpidruro' or 'tpidrprw' use the three CP15 registers. 'cp15' is an alias for 'tpidruro'. "
+           "For AArch64: 'tpidr_el0', 'tpidr_el1', 'tpidr_el2', 'tpidr_el3' or 'tpidrro_el0' use the five system registers. 'elN' is an alias for 'tpidr_elN'.">;
 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>;

diff  --git a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
index f3bc00188c784..3547031635795 100644
--- a/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -291,13 +291,15 @@ void aarch64::getAArch64TargetFeatures(const Driver &D,
 
   if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
     StringRef Mtp = A->getValue();
-    if (Mtp == "el3")
+    if (Mtp == "el3" || Mtp == "tpidr_el3")
       Features.push_back("+tpidr-el3");
-    else if (Mtp == "el2")
+    else if (Mtp == "el2" || Mtp == "tpidr_el2")
       Features.push_back("+tpidr-el2");
-    else if (Mtp == "el1")
+    else if (Mtp == "el1" || Mtp == "tpidr_el1")
       Features.push_back("+tpidr-el1");
-    else if (Mtp != "el0")
+    else if (Mtp == "tpidrro_el0")
+      Features.push_back("+tpidrro-el0");
+    else if (Mtp != "el0" && Mtp != "tpidr_el0")
       D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
   }
 

diff  --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
index 2ff18a47ef77a..4f2475efa18b8 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -184,11 +184,16 @@ arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args,
   if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
     arm::ReadTPMode ThreadPointer =
         llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
-            .Case("cp15", ReadTPMode::Cp15)
+            .Case("cp15", ReadTPMode::TPIDRURO)
+            .Case("tpidrurw", ReadTPMode::TPIDRURW)
+            .Case("tpidruro", ReadTPMode::TPIDRURO)
+            .Case("tpidrprw", ReadTPMode::TPIDRPRW)
             .Case("soft", ReadTPMode::Soft)
             .Default(ReadTPMode::Invalid);
-    if (ThreadPointer == ReadTPMode::Cp15 && !isHardTPSupported(Triple) &&
-        !ForAS) {
+    if ((ThreadPointer == ReadTPMode::TPIDRURW ||
+         ThreadPointer == ReadTPMode::TPIDRURO ||
+         ThreadPointer == ReadTPMode::TPIDRPRW) &&
+        !isHardTPSupported(Triple) && !ForAS) {
       D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName();
       return ReadTPMode::Invalid;
     }
@@ -521,8 +526,12 @@ llvm::ARM::FPUKind arm::getARMTargetFeatures(const Driver &D,
     }
   }
 
-  if (getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::Cp15)
-    Features.push_back("+read-tp-hard");
+  if (getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRURW)
+    Features.push_back("+read-tp-tpidrurw");
+  if (getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRURO)
+    Features.push_back("+read-tp-tpidruro");
+  if (getReadTPMode(D, Args, Triple, ForAS) == ReadTPMode::TPIDRPRW)
+    Features.push_back("+read-tp-tpidrprw");
 
   const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
   const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);

diff  --git a/clang/lib/Driver/ToolChains/Arch/ARM.h b/clang/lib/Driver/ToolChains/Arch/ARM.h
index 08696ad28931f..83a4da6844677 100644
--- a/clang/lib/Driver/ToolChains/Arch/ARM.h
+++ b/clang/lib/Driver/ToolChains/Arch/ARM.h
@@ -37,7 +37,9 @@ void appendBE8LinkFlag(const llvm::opt::ArgList &Args,
 enum class ReadTPMode {
   Invalid,
   Soft,
-  Cp15,
+  TPIDRURW,
+  TPIDRURO,
+  TPIDRPRW,
 };
 
 enum class FloatABI {

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 7ee39da952b20..5abc5e4456af2 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3381,7 +3381,7 @@ static void RenderSSPOptions(const Driver &D, const ToolChain &TC,
         }
       }
       CmdArgs.push_back("-target-feature");
-      CmdArgs.push_back("+read-tp-hard");
+      CmdArgs.push_back("+read-tp-tpidruro");
     }
     if (EffectiveTriple.isAArch64() && Value != "sysreg" && Value != "global") {
       D.Diag(diag::err_drv_invalid_value_with_suggestion)

diff  --git a/clang/test/Driver/aarch64-thread-pointer.c b/clang/test/Driver/aarch64-thread-pointer.c
new file mode 100644
index 0000000000000..6a5d4ba0852ed
--- /dev/null
+++ b/clang/test/Driver/aarch64-thread-pointer.c
@@ -0,0 +1,47 @@
+// Test of the AArch64 values of -mtp=, checking that each one maps to
+// the right target features.
+
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=el0 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=tpidr_el0 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s
+// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidrro-el0"
+// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=tpidrro_el0 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_ROEL0 %s
+// ARMv8_THREAD_POINTER_ROEL0:     "-target-feature" "+tpidrro-el0"
+// ARMv8_THREAD_POINTER_ROEL0-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_ROEL0-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_ROEL0-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=el1 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL1 %s
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=tpidr_el1 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL1 %s
+// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidrro-el0"
+// ARMv8_THREAD_POINTER_EL1:     "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=el2 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL2 %s
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=tpidr_el2 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL2 %s
+// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidrro-el0"
+// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL2:     "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el3"
+
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=el3 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL3 %s
+// RUN: %clang --target=aarch64-linux -### -S %s -arch armv8a -mtp=tpidr_el3 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL3 %s
+// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidrro-el0"
+// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el1"
+// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el2"
+// ARMv8_THREAD_POINTER_EL3:     "-target-feature" "+tpidr-el3"

diff  --git a/clang/test/Driver/arm-thread-pointer.c b/clang/test/Driver/arm-thread-pointer.c
new file mode 100644
index 0000000000000..d512a04786e1d
--- /dev/null
+++ b/clang/test/Driver/arm-thread-pointer.c
@@ -0,0 +1,45 @@
+// Test of the AArch32 values of -mtp=, checking that each one maps to
+// the right target features.
+
+// RUN: %clang --target=armv7-linux -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s
+// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-tpidruro"
+
+// RUN: %clang --target=armv7-linux -mtp=tpidruro -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s
+// RUN: %clang --target=armv7-linux -mtp=tpidrurw -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-TPIDRURW %s
+// ARMv7_THREAD_POINTER-TPIDRURW: "-target-feature" "+read-tp-tpidrurw"
+// RUN: %clang --target=armv7-linux -mtp=tpidrprw -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-TPIDRPRW %s
+// ARMv7_THREAD_POINTER-TPIDRPRW: "-target-feature" "+read-tp-tpidrprw"
+
+// RUN: %clang --target=armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
+// RUN: %clang --target=thumbv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
+// RUN: %clang --target=armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
+// RUN: %clang --target=armv6-linux -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
+// RUN: %clang --target=armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
+// ARM_THREAD_POINTER-HARD: "-target-feature" "+read-tp-tpidruro"
+
+// RUN: %clang --target=armv5t-linux -mtp=cp15 -x assembler -### %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_ASSEMBLER %s
+// ARMv5_THREAD_POINTER_ASSEMBLER-NOT: hardware TLS register is not supported for the armv5 sub-architecture
+
+// RUN: %clang --target=armv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s
+// RUN: %clang --target=thumbv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s
+// THUMBv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the thumbv6 sub-architecture
+
+// RUN: %clang --target=armv7-linux -mtp=soft -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s
+// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-tpidruro"
+
+// RUN: %clang --target=armv7-linux -### -S %s 2>&1 | \
+// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s
+// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-tpidruro"

diff  --git a/clang/test/Driver/clang-translation.c b/clang/test/Driver/clang-translation.c
index 4e42ab3a9e2e8..02f732d287689 100644
--- a/clang/test/Driver/clang-translation.c
+++ b/clang/test/Driver/clang-translation.c
@@ -126,70 +126,6 @@
 // ARMV5E: "-cc1"
 // ARMV5E: "-target-cpu" "arm1022e"
 
-// RUN: %clang -target armv7-linux -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER-HARD %s
-// ARMv7_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard"
-
-// RUN: %clang -target armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
-// RUN: %clang -target thumbv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
-// RUN: %clang -target armv6k-linux -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
-// RUN: %clang -target armv6-linux -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
-// RUN: %clang -target armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARM_THREAD_POINTER-HARD %s
-// ARM_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard"
-
-// RUN: %clang -target armv5t-linux -mtp=cp15 -x assembler -### %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_ASSEMBLER %s
-// ARMv5_THREAD_POINTER_ASSEMBLER-NOT: hardware TLS register is not supported for the armv5 sub-architecture
-
-// RUN: %clang -target armv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s
-// RUN: %clang -target thumbv6-linux -mthumb -mtp=cp15 -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=THUMBv6_THREAD_POINTER_UNSUPP %s
-// THUMBv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the thumbv6 sub-architecture
-
-// RUN: %clang -target armv7-linux -mtp=soft -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_SOFT %s
-// ARMv7_THREAD_POINTER_SOFT-NOT: "-target-feature" "+read-tp-hard"
-
-// RUN: %clang -target armv7-linux -### -S %s 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s
-// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard"
-
-// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_NON %s
-// ARMv8_THREAD_POINTER_NON-NOT: "-target-feature" "+tpidr-el1"
-// ARMv8_THREAD_POINTER_NON-NOT: "-target-feature" "+tpidr-el2"
-// ARMv8_THREAD_POINTER_NON-NOT: "-target-feature" "+tpidr-el3"
-
-// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el0 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL0 %s
-// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el1"
-// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el2"
-// ARMv8_THREAD_POINTER_EL0-NOT: "-target-feature" "+tpidr-el3"
-
-// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el1 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL1 %s
-// ARMv8_THREAD_POINTER_EL1: "-target-feature" "+tpidr-el1"
-// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el2"
-// ARMv8_THREAD_POINTER_EL1-NOT: "-target-feature" "+tpidr-el3"
-
-// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el2 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL2 %s
-// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el1"
-// ARMv8_THREAD_POINTER_EL2: "-target-feature" "+tpidr-el2"
-// ARMv8_THREAD_POINTER_EL2-NOT: "-target-feature" "+tpidr-el3"
-
-// RUN: %clang -target aarch64-linux -### -S %s -arch armv8a -mtp=el3 2>&1 | \
-// RUN: FileCheck -check-prefix=ARMv8_THREAD_POINTER_EL3 %s
-// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el1"
-// ARMv8_THREAD_POINTER_EL3-NOT: "-target-feature" "+tpidr-el2"
-// ARMv8_THREAD_POINTER_EL3: "-target-feature" "+tpidr-el3"
-
 // RUN: %clang -target powerpc64-unknown-linux-gnu \
 // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s
 // PPCG5: clang

diff  --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index f7e676435230d..75b02acf4ca1c 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -690,6 +690,8 @@ include "AArch64SystemOperands.td"
 foreach i = 1-3 in
 def FeatureUseEL#i#ForTP : SubtargetFeature<"tpidr-el"#i, "UseEL"#i#"ForTP",
   "true", "Permit use of TPIDR_EL"#i#" for the TLS base">;
+def FeatureUseROEL0ForTP : SubtargetFeature<"tpidrro-el0", "UseROEL0ForTP",
+  "true", "Permit use of TPIDRRO_EL0 for the TLS base">;
 
 //===----------------------------------------------------------------------===//
 // Control codegen mitigation against Straight Line Speculation vulnerability.

diff  --git a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
index eaf5775eb971a..dcb73ae2dce2b 100644
--- a/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -1340,6 +1340,8 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
       SysReg = AArch64SysReg::TPIDR_EL2;
     else if (MF->getSubtarget<AArch64Subtarget>().useEL1ForTP())
       SysReg = AArch64SysReg::TPIDR_EL1;
+    else if (MF->getSubtarget<AArch64Subtarget>().useROEL0ForTP())
+      SysReg = AArch64SysReg::TPIDRRO_EL0;
     BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(AArch64::MRS), DstReg)
         .addImm(SysReg);
     MI.eraseFromParent();

diff  --git a/llvm/lib/Target/ARM/ARM.td b/llvm/lib/Target/ARM/ARM.td
index 5ccc603f6b426..4bb20271d0f28 100644
--- a/llvm/lib/Target/ARM/ARM.td
+++ b/llvm/lib/Target/ARM/ARM.td
@@ -228,10 +228,13 @@ def FeatureFuseAES        : SubtargetFeature<"fuse-aes", "HasFuseAES", "true",
 def FeatureFuseLiterals   : SubtargetFeature<"fuse-literals", "HasFuseLiterals", "true",
                                              "CPU fuses literal generation operations">;
 
-// The way of reading thread pointer.
-// True if read thread pointer from coprocessor register.
-def FeatureReadTp :  SubtargetFeature<"read-tp-hard", "IsReadTPHard", "true",
-                                      "Reading thread pointer from register">;
+// Choice of hardware register to use as the thread pointer, if any.
+def FeatureReadTpTPIDRURW :  SubtargetFeature<"read-tp-tpidrurw", "IsReadTPTPIDRURW", "true",
+                                      "Reading thread pointer from TPIDRURW register">;
+def FeatureReadTpTPIDRURO :  SubtargetFeature<"read-tp-tpidruro", "IsReadTPTPIDRURO", "true",
+                                      "Reading thread pointer from TPIDRURO register">;
+def FeatureReadTpTPIDRPRW :  SubtargetFeature<"read-tp-tpidrprw", "IsReadTPTPIDRPRW", "true",
+                                      "Reading thread pointer from TPIDRPRW register">;
 
 // Cyclone can zero VFP registers in 0 cycles.
 // True if the instructions "vmov.i32 d0, #0" and "vmov.i32 q0, #0" are

diff  --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
index 2ffa540a7e2f8..2e165f7c25e72 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -4939,7 +4939,7 @@ void ARMBaseInstrInfo::expandLoadStackGuardBase(MachineBasicBlock::iterator MI,
   unsigned int Offset = 0;
 
   if (LoadImmOpc == ARM::MRC || LoadImmOpc == ARM::t2MRC) {
-    assert(Subtarget.isReadTPHard() &&
+    assert(!Subtarget.isReadTPSoft() &&
            "TLS stack protector requires hardware TLS register");
 
     BuildMI(MBB, MI, DL, get(LoadImmOpc), Reg)

diff  --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index fc078b1673343..a32478e6ddfbf 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -5903,8 +5903,12 @@ let isCall = 1,
 }
 
 // Reading thread pointer from coprocessor register
+def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 2)>,
+      Requires<[IsARM, IsReadTPTPIDRURW]>;
 def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>,
-      Requires<[IsARM, IsReadTPHard]>;
+      Requires<[IsARM, IsReadTPTPIDRURO]>;
+def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 4)>,
+      Requires<[IsARM, IsReadTPTPIDRPRW]>;
 
 //===----------------------------------------------------------------------===//
 // SJLJ Exception handling intrinsics

diff  --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td
index 2a84de5434725..610a71d68ec8c 100644
--- a/llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -4780,8 +4780,12 @@ def t2CDP2 : T2Cop<0b1111, (outs), (ins p_imm:$cop, imm0_15:$opc1,
 
 
 // Reading thread pointer from coprocessor register
+def : T2Pat<(ARMthread_pointer), (t2MRC 15, 0, 13, 0, 2)>,
+      Requires<[IsThumb2, IsReadTPTPIDRURW]>;
 def : T2Pat<(ARMthread_pointer), (t2MRC 15, 0, 13, 0, 3)>,
-      Requires<[IsThumb2, IsReadTPHard]>;
+      Requires<[IsThumb2, IsReadTPTPIDRURO]>;
+def : T2Pat<(ARMthread_pointer), (t2MRC 15, 0, 13, 0, 4)>,
+      Requires<[IsThumb2, IsReadTPTPIDRPRW]>;
 
 //===----------------------------------------------------------------------===//
 // ARMv8.1 Privilege Access Never extension

diff  --git a/llvm/lib/Target/ARM/ARMPredicates.td b/llvm/lib/Target/ARM/ARMPredicates.td
index 59562efea6b96..2172ea9008517 100644
--- a/llvm/lib/Target/ARM/ARMPredicates.td
+++ b/llvm/lib/Target/ARM/ARMPredicates.td
@@ -170,8 +170,10 @@ def IsNotMachO       : Predicate<"!Subtarget->isTargetMachO()">;
 def IsNaCl           : Predicate<"Subtarget->isTargetNaCl()">;
 def IsWindows        : Predicate<"Subtarget->isTargetWindows()">;
 def IsNotWindows     : Predicate<"!Subtarget->isTargetWindows()">;
-def IsReadTPHard     : Predicate<"Subtarget->isReadTPHard()">;
-def IsReadTPSoft     : Predicate<"!Subtarget->isReadTPHard()">;
+def IsReadTPTPIDRURW : Predicate<"Subtarget->isReadTPTPIDRURW()">;
+def IsReadTPTPIDRURO : Predicate<"Subtarget->isReadTPTPIDRURO()">;
+def IsReadTPTPIDRPRW : Predicate<"Subtarget->isReadTPTPIDRPRW()">;
+def IsReadTPSoft     : Predicate<"Subtarget->isReadTPSoft()">;
 def UseNaClTrap      : Predicate<"Subtarget->useNaClTrap()">,
                                  AssemblerPredicate<(all_of FeatureNaClTrap), "NaCl">;
 def DontUseNaClTrap  : Predicate<"!Subtarget->useNaClTrap()">;

diff  --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index c959ca59aaf5d..c6a845bbe4b54 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -402,6 +402,10 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
 
   bool isTargetHardFloat() const;
 
+  bool isReadTPSoft() const {
+    return !(isReadTPTPIDRURW() || isReadTPTPIDRURO() || isReadTPTPIDRPRW());
+  }
+
   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
 
   bool isXRaySupported() const override;

diff  --git a/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll b/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll
index 63f4cb0c1fdaf..679e4ac0bd27c 100644
--- a/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll
+++ b/llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll
@@ -1,5 +1,6 @@
 ; RUN: llc < %s -mtriple=aarch64-linux-gnu | FileCheck %s
 ; RUN: llc < %s -mtriple=aarch64-fuchsia | FileCheck %s
+; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+tpidrro-el0 | FileCheck --check-prefix=USEROEL0 %s
 ; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+tpidr-el1 | FileCheck --check-prefix=USEEL1 %s
 ; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+tpidr-el2 | FileCheck --check-prefix=USEEL2 %s
 ; RUN: llc < %s -mtriple=aarch64-linux-gnu -mattr=+tpidr-el3 | FileCheck --check-prefix=USEEL3 %s
@@ -10,6 +11,8 @@ declare ptr @llvm.thread.pointer() #1
 define ptr @thread_pointer() {
 ; CHECK: thread_pointer:
 ; CHECK: mrs {{x[0-9]+}}, TPIDR_EL0
+; USEROEL0: thread_pointer:
+; USEROEL0: mrs {{x[0-9]+}}, TPIDRRO_EL0
 ; USEEL1: thread_pointer:
 ; USEEL1: mrs {{x[0-9]+}}, TPIDR_EL1
 ; USEEL2: thread_pointer:

diff  --git a/llvm/test/CodeGen/ARM/readtp.ll b/llvm/test/CodeGen/ARM/readtp.ll
index c8675d8c2ffe4..dedd16cc49bf8 100644
--- a/llvm/test/CodeGen/ARM/readtp.ll
+++ b/llvm/test/CodeGen/ARM/readtp.ll
@@ -1,6 +1,10 @@
-; RUN: llc -mtriple=armeb-linux-gnueabihf -O2 -mattr=+read-tp-hard %s -o - | FileCheck %s -check-prefix=CHECK-HARD
+; RUN: llc -mtriple=armeb-linux-gnueabihf -O2 -mattr=+read-tp-tpidrurw %s -o - | FileCheck %s -check-prefix=CHECK-TPIDRURW
+; RUN: llc -mtriple=armeb-linux-gnueabihf -O2 -mattr=+read-tp-tpidruro %s -o - | FileCheck %s -check-prefix=CHECK-TPIDRURO
+; RUN: llc -mtriple=armeb-linux-gnueabihf -O2 -mattr=+read-tp-tpidrprw %s -o - | FileCheck %s -check-prefix=CHECK-TPIDRPRW
 ; RUN: llc -mtriple=armeb-linux-gnueabihf -O2 %s -o - | FileCheck %s -check-prefix=CHECK-SOFT
-; RUN: llc -mtriple=thumbv7-linux-gnueabihf -O2 -mattr=+read-tp-hard %s -o - | FileCheck %s -check-prefix=CHECK-HARD
+; RUN: llc -mtriple=thumbv7-linux-gnueabihf -O2 -mattr=+read-tp-tpidrurw %s -o - | FileCheck %s -check-prefix=CHECK-TPIDRURW
+; RUN: llc -mtriple=thumbv7-linux-gnueabihf -O2 -mattr=+read-tp-tpidruro %s -o - | FileCheck %s -check-prefix=CHECK-TPIDRURO
+; RUN: llc -mtriple=thumbv7-linux-gnueabihf -O2 -mattr=+read-tp-tpidrprw %s -o - | FileCheck %s -check-prefix=CHECK-TPIDRPRW
 ; RUN: llc -mtriple=thumbv7-linux-gnueabihf -O2 %s -o - | FileCheck %s -check-prefix=CHECK-SOFT
 
 
@@ -20,5 +24,7 @@ entry:
 
 
 ; CHECK-LABEL: foo:
-; CHECK-HARD:    mrc	p15, #0, {{r[0-9]+}}, c13, c0, #3
-; CHECK-SOFT:    bl	__aeabi_read_tp
+; CHECK-TPIDRURW:     mrc	p15, #0, {{r[0-9]+}}, c13, c0, #2
+; CHECK-TPIDRURO:     mrc	p15, #0, {{r[0-9]+}}, c13, c0, #3
+; CHECK-TPIDRPRW:     mrc	p15, #0, {{r[0-9]+}}, c13, c0, #4
+; CHECK-SOFT:         bl	__aeabi_read_tp

diff  --git a/llvm/test/CodeGen/ARM/stack-guard-tls.ll b/llvm/test/CodeGen/ARM/stack-guard-tls.ll
index 6c3fe43ab31ce..fec3235b07df5 100644
--- a/llvm/test/CodeGen/ARM/stack-guard-tls.ll
+++ b/llvm/test/CodeGen/ARM/stack-guard-tls.ll
@@ -1,13 +1,13 @@
 ; RUN: split-file %s %t
 ; RUN: cat %t/main.ll %t/a.ll > %t/a2.ll
 ; RUN: cat %t/main.ll %t/b.ll > %t/b2.ll
-; RUN: llc %t/a2.ll -mtriple=armv7-unknown-linux-gnueabihf -mattr=+read-tp-hard -o - | \
+; RUN: llc %t/a2.ll -mtriple=armv7-unknown-linux-gnueabihf -mattr=+read-tp-tpidruro -o - | \
 ; RUN: FileCheck --check-prefixes=CHECK,CHECK-SMALL %s
-; RUN: llc %t/a2.ll -mtriple=thumbv7-unknown-linux-gnueabihf -mattr=+read-tp-hard -o - | \
+; RUN: llc %t/a2.ll -mtriple=thumbv7-unknown-linux-gnueabihf -mattr=+read-tp-tpidruro -o - | \
 ; RUN: FileCheck --check-prefixes=CHECK,CHECK-SMALL %s
-; RUN: llc %t/b2.ll -mtriple=armv7-unknown-linux-gnueabihf -mattr=+read-tp-hard -o - | \
+; RUN: llc %t/b2.ll -mtriple=armv7-unknown-linux-gnueabihf -mattr=+read-tp-tpidruro -o - | \
 ; RUN: FileCheck --check-prefixes=CHECK,CHECK-LARGE %s
-; RUN: llc %t/b2.ll -mtriple=thumbv7-unknown-linux-gnueabihf -mattr=+read-tp-hard -o - | \
+; RUN: llc %t/b2.ll -mtriple=thumbv7-unknown-linux-gnueabihf -mattr=+read-tp-tpidruro -o - | \
 ; RUN: FileCheck --check-prefixes=CHECK,CHECK-LARGE %s
 
 ;--- main.ll

diff  --git a/llvm/test/CodeGen/ARM/thread_pointer.ll b/llvm/test/CodeGen/ARM/thread_pointer.ll
index 95d4467dc1e29..283ccde544e1c 100644
--- a/llvm/test/CodeGen/ARM/thread_pointer.ll
+++ b/llvm/test/CodeGen/ARM/thread_pointer.ll
@@ -1,7 +1,11 @@
 ; RUN: llc -mtriple arm-linux-gnueabi -o - %s | FileCheck %s -check-prefix=CHECK-SOFT
-; RUN: llc -mtriple arm-linux-gnueabi -mattr=+read-tp-hard -o - %s | FileCheck %s -check-prefix=CHECK-HARD
+; RUN: llc -mtriple arm-linux-gnueabi -mattr=+read-tp-tpidrurw -o - %s | FileCheck %s -check-prefix=CHECK-TPIDRURW
+; RUN: llc -mtriple arm-linux-gnueabi -mattr=+read-tp-tpidruro -o - %s | FileCheck %s -check-prefix=CHECK-TPIDRURO
+; RUN: llc -mtriple arm-linux-gnueabi -mattr=+read-tp-tpidrprw -o - %s | FileCheck %s -check-prefix=CHECK-TPIDRPRW
 ; RUN: llc -mtriple thumbv7-linux-gnueabi -o - %s | FileCheck %s -check-prefix=CHECK-SOFT
-; RUN: llc -mtriple thumbv7-linux-gnueabi -mattr=+read-tp-hard -o - %s | FileCheck %s -check-prefix=CHECK-HARD
+; RUN: llc -mtriple thumbv7-linux-gnueabi -mattr=+read-tp-tpidrurw -o - %s | FileCheck %s -check-prefix=CHECK-TPIDRURW
+; RUN: llc -mtriple thumbv7-linux-gnueabi -mattr=+read-tp-tpidruro -o - %s | FileCheck %s -check-prefix=CHECK-TPIDRURO
+; RUN: llc -mtriple thumbv7-linux-gnueabi -mattr=+read-tp-tpidrprw -o - %s | FileCheck %s -check-prefix=CHECK-TPIDRPRW
 
 declare ptr @llvm.thread.pointer()
 
@@ -11,6 +15,8 @@ entry:
   ret ptr %tmp1
 }
 
-; CHECK-SOFT: bl __aeabi_read_tp
-; CHECK-HARD: mrc p15, #0, {{r[0-9]+}}, c13, c0, #3
+; CHECK-SOFT:     bl __aeabi_read_tp
+; CHECK-TPIDRURW: mrc p15, #0, {{r[0-9]+}}, c13, c0, #2
+; CHECK-TPIDRURO: mrc p15, #0, {{r[0-9]+}}, c13, c0, #3
+; CHECK-TPIDRPRW: mrc p15, #0, {{r[0-9]+}}, c13, c0, #4
 


        


More information about the cfe-commits mailing list