diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/ARM.td | 4 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 9 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMSubtarget.h | 4 |
3 files changed, 16 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; |