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, def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; let Flags = [TargetSpecific] in { -def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft,cp15,el0,el1,el2,el3">, - HelpText<"Thread pointer access method (AArch32/AArch64 only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, 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; // Alias for GCC compatibility def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias; def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, 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(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().useEL1ForTP()) SysReg = AArch64SysReg::TPIDR_EL1; + else if (MF->getSubtarget().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