simon_tatham created this revision.
simon_tatham added reviewers: nickdesaulniers, peter.smith, kristof.beyls, 
t.p.northover, rengolin.
Herald added a subscriber: hiraditya.
Herald added a project: All.
simon_tatham requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, MaskRay.
Herald added projects: clang, LLVM.

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 the one that's read-only at EL0. 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:

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

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).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D152433

Files:
  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/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

Index: llvm/test/CodeGen/ARM/thread_pointer.ll
===================================================================
--- llvm/test/CodeGen/ARM/thread_pointer.ll
+++ 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 @@
   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
 
Index: llvm/test/CodeGen/ARM/stack-guard-tls.ll
===================================================================
--- llvm/test/CodeGen/ARM/stack-guard-tls.ll
+++ 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
Index: llvm/test/CodeGen/ARM/readtp.ll
===================================================================
--- llvm/test/CodeGen/ARM/readtp.ll
+++ 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 @@
 
 
 ; 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
Index: llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll
===================================================================
--- llvm/test/CodeGen/AArch64/arm64-builtins-linux.ll
+++ 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 @@
 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:
Index: llvm/lib/Target/ARM/ARMPredicates.td
===================================================================
--- llvm/lib/Target/ARM/ARMPredicates.td
+++ llvm/lib/Target/ARM/ARMPredicates.td
@@ -170,8 +170,12 @@
 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->isReadTPTPIDRURW() && "
+                                 "!Subtarget->isReadTPTPIDRURO() && "
+                                 "!Subtarget->isReadTPTPIDRPRW()">;
 def UseNaClTrap      : Predicate<"Subtarget->useNaClTrap()">,
                                  AssemblerPredicate<(all_of FeatureNaClTrap), "NaCl">;
 def DontUseNaClTrap  : Predicate<"!Subtarget->useNaClTrap()">;
Index: llvm/lib/Target/ARM/ARMInstrThumb2.td
===================================================================
--- llvm/lib/Target/ARM/ARMInstrThumb2.td
+++ llvm/lib/Target/ARM/ARMInstrThumb2.td
@@ -4780,8 +4780,12 @@
 
 
 // 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
Index: llvm/lib/Target/ARM/ARMInstrInfo.td
===================================================================
--- llvm/lib/Target/ARM/ARMInstrInfo.td
+++ llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -5903,8 +5903,12 @@
 }
 
 // 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
Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
===================================================================
--- llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
+++ llvm/lib/Target/ARM/ARMBaseInstrInfo.cpp
@@ -4939,7 +4939,7 @@
   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)
Index: llvm/lib/Target/ARM/ARM.td
===================================================================
--- llvm/lib/Target/ARM/ARM.td
+++ llvm/lib/Target/ARM/ARM.td
@@ -228,10 +228,13 @@
 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
Index: llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
===================================================================
--- llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
+++ llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp
@@ -1340,6 +1340,8 @@
       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();
Index: llvm/lib/Target/AArch64/AArch64.td
===================================================================
--- llvm/lib/Target/AArch64/AArch64.td
+++ llvm/lib/Target/AArch64/AArch64.td
@@ -690,6 +690,8 @@
 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.
Index: clang/test/Driver/clang-translation.c
===================================================================
--- clang/test/Driver/clang-translation.c
+++ clang/test/Driver/clang-translation.c
@@ -128,7 +128,16 @@
 
 // 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"
+// 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
@@ -140,7 +149,7 @@
 // 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"
+// 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
@@ -154,38 +163,58 @@
 
 // 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"
+// 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-hard"
+// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-tpidruro"
 
 // 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" "+tpidrro-el0"
 // 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
+// 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"
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3372,7 +3372,7 @@
         }
       }
       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)
Index: clang/lib/Driver/ToolChains/Arch/ARM.h
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.h
+++ clang/lib/Driver/ToolChains/Arch/ARM.h
@@ -37,7 +37,9 @@
 enum class ReadTPMode {
   Invalid,
   Soft,
-  Cp15,
+  TPIDRURW,
+  TPIDRURO,
+  TPIDRPRW,
 };
 
 enum class FloatABI {
Index: clang/lib/Driver/ToolChains/Arch/ARM.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/ARM.cpp
+++ clang/lib/Driver/ToolChains/Arch/ARM.cpp
@@ -184,10 +184,15 @@
   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) &&
+    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;
@@ -519,8 +524,12 @@
     }
   }
 
-  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);
Index: clang/lib/Driver/ToolChains/Arch/AArch64.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Arch/AArch64.cpp
+++ clang/lib/Driver/ToolChains/Arch/AArch64.cpp
@@ -291,13 +291,15 @@
 
   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);
   }
 
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -3519,8 +3519,10 @@
   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,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>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to