simon_tatham updated this revision to Diff 530830.
simon_tatham added a comment.

Rebased past rG34d7acd444b8 
<https://reviews.llvm.org/rG34d7acd444b88342fc93fca202608c1e16fa5946> (which 
conflicted with it, though trivially) and attempted to fix the clang-format 
complaint in pre-merge checks.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D152433/new/

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/aarch64-thread-pointer.c
  clang/test/Driver/arm-thread-pointer.c
  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

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/ARMSubtarget.h
===================================================================
--- llvm/lib/Target/ARM/ARMSubtarget.h
+++ llvm/lib/Target/ARM/ARMSubtarget.h
@@ -402,6 +402,10 @@
 
   bool isTargetHardFloat() const;
 
+  bool isReadTPSoft() const {
+    return !(isReadTPTPIDRURW() || isReadTPTPIDRURO() || isReadTPTPIDRPRW());
+  }
+
   bool isTargetAndroid() const { return TargetTriple.isAndroid(); }
 
   bool isXRaySupported() const override;
Index: llvm/lib/Target/ARM/ARMPredicates.td
===================================================================
--- llvm/lib/Target/ARM/ARMPredicates.td
+++ llvm/lib/Target/ARM/ARMPredicates.td
@@ -170,8 +170,10 @@
 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()">;
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
@@ -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
Index: clang/test/Driver/arm-thread-pointer.c
===================================================================
--- /dev/null
+++ 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"
Index: clang/test/Driver/aarch64-thread-pointer.c
===================================================================
--- /dev/null
+++ 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"
Index: clang/lib/Driver/ToolChains/Clang.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Clang.cpp
+++ clang/lib/Driver/ToolChains/Clang.cpp
@@ -3375,7 +3375,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,11 +184,16 @@
   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;
     }
@@ -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
@@ -3545,8 +3545,10 @@
 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>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to