summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/ARM/ARM.td4
-rw-r--r--llvm/lib/Target/ARM/ARMInstrInfo.td9
-rw-r--r--llvm/lib/Target/ARM/ARMSubtarget.h4
-rw-r--r--llvm/test/CodeGen/ARM/readtp.ll22
4 files changed, 38 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/ARM.td b/llvm/lib/Target/ARM/ARM.td
index 9c691f548fa..487a2d50bbe 100644
--- a/llvm/lib/Target/ARM/ARM.td
+++ b/llvm/lib/Target/ARM/ARM.td
@@ -129,6 +129,10 @@ def FeatureFPAO : SubtargetFeature<"fpao", "HasFPAO", "true",
def FeatureFuseAES : SubtargetFeature<"fuse-aes", "HasFuseAES", "true",
"CPU fuses AES crypto operations">;
+// The way of reading thread pointer
+def FeatureReadTp : SubtargetFeature<"read-tp-hard", "ReadTPHard", "true",
+ "Reading thread pointer from register">;
+
// Cyclone can zero VFP registers in 0 cycles.
def FeatureZCZeroing : SubtargetFeature<"zcz", "HasZeroCycleZeroing", "true",
"Has zero-cycle zeroing instructions">;
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td
index d06b7d0896f..25efe0ff18e 100644
--- a/llvm/lib/Target/ARM/ARMInstrInfo.td
+++ b/llvm/lib/Target/ARM/ARMInstrInfo.td
@@ -313,6 +313,8 @@ 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 UseNaClTrap : Predicate<"Subtarget->useNaClTrap()">,
AssemblerPredicate<"FeatureNaClTrap", "NaCl">;
def DontUseNaClTrap : Predicate<"!Subtarget->useNaClTrap()">;
@@ -5519,9 +5521,14 @@ let usesCustomInserter = 1, Defs = [CPSR] in
let isCall = 1,
Defs = [R0, R12, LR, CPSR], Uses = [SP] in {
def TPsoft : ARMPseudoInst<(outs), (ins), 4, IIC_Br,
- [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>;
+ [(set R0, ARMthread_pointer)]>, Sched<[WriteBr]>,
+ Requires<[IsARM, IsReadTPSoft]>;
}
+// Reading thread pointer from coprocessor register
+def : ARMPat<(ARMthread_pointer), (MRC 15, 0, 13, 0, 3)>,
+ Requires<[IsARM, IsReadTPHard]>;
+
//===----------------------------------------------------------------------===//
// SJLJ Exception handling intrinsics
// eh_sjlj_setjmp() is an instruction sequence to store the return
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index 400d185e9fd..c49ea133836 100644
--- a/llvm/lib/Target/ARM/ARMSubtarget.h
+++ b/llvm/lib/Target/ARM/ARMSubtarget.h
@@ -331,6 +331,9 @@ protected:
/// If true, VFP/NEON VMLA/VMLS have special RAW hazards.
bool HasVMLxHazards = false;
+ // If true, read thread pointer from coprocessor register.
+ bool ReadTPHard = false;
+
/// If true, VMOVRS, VMOVSR and VMOVS will be converted from VFP to NEON.
bool UseNEONForFPMovs = false;
@@ -657,6 +660,7 @@ public:
bool isMClass() const { return ARMProcClass == MClass; }
bool isRClass() const { return ARMProcClass == RClass; }
bool isAClass() const { return ARMProcClass == AClass; }
+ bool isReadTPHard() const { return ReadTPHard; }
bool isR9Reserved() const {
return isTargetMachO() ? (ReserveR9 || !HasV6Ops) : ReserveR9;
diff --git a/llvm/test/CodeGen/ARM/readtp.ll b/llvm/test/CodeGen/ARM/readtp.ll
new file mode 100644
index 00000000000..01ebf6e765f
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/readtp.ll
@@ -0,0 +1,22 @@
+; 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 %s -o - | FileCheck %s -check-prefix=CHECK-SOFT
+
+
+; __thread int counter;
+; void foo() {
+; counter = 5;
+; }
+
+
+@counter = thread_local local_unnamed_addr global i32 0, align 4
+
+define void @foo() local_unnamed_addr #0 {
+entry:
+ store i32 5, i32* @counter, align 4
+ ret void
+}
+
+
+; CHECK-LABEL: foo:
+; CHECK-HARD: mrc p15, #0, {{r[0-9]+}}, c13, c0, #3
+; CHECK-SOFT: bl __aeabi_read_tp \ No newline at end of file
OpenPOWER on IntegriCloud