diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.h b/clang/lib/Driver/ToolChains/Arch/ARM.h --- a/clang/lib/Driver/ToolChains/Arch/ARM.h +++ b/clang/lib/Driver/ToolChains/Arch/ARM.h @@ -53,7 +53,8 @@ const llvm::opt::ArgList &Args); void setFloatABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, llvm::Triple &triple); -ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args); +ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args, + const llvm::Triple &Triple); void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args, types::ID InputType, llvm::Triple &Triple); diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -148,13 +148,21 @@ } // Select mode for reading thread pointer (-mtp=soft/cp15). -arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args) { +arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args, + const llvm::Triple &Triple) { if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { arm::ReadTPMode ThreadPointer = llvm::StringSwitch(A->getValue()) .Case("cp15", ReadTPMode::Cp15) .Case("soft", ReadTPMode::Soft) .Default(ReadTPMode::Invalid); + if (ThreadPointer == ReadTPMode::Cp15 && + getARMSubArchVersionNumber(Triple) < 7 && + llvm::ARM::parseArch(Triple.getArchName()) != + llvm::ARM::ArchKind::ARMV6T2) { + D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName(); + return ReadTPMode::Invalid; + } if (ThreadPointer != ReadTPMode::Invalid) return ThreadPointer; if (StringRef(A->getValue()).empty()) @@ -422,7 +430,7 @@ bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args); - arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args, Triple); llvm::Optional> WaCPU, WaFPU, WaHDiv, WaArch; diff --git a/clang/test/Driver/clang-translation.c b/clang/test/Driver/clang-translation.c --- a/clang/test/Driver/clang-translation.c +++ b/clang/test/Driver/clang-translation.c @@ -110,15 +110,27 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" -// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 2>&1 | \ +// 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 arm-linux -mtp=soft -### -S %s -arch armv7 2>&1 | \ +// RUN: %clang -target armv6t2-linux -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv6T2_THREAD_POINTER-HARD %s +// ARMv6T2_THREAD_POINTER-HARD: "-target-feature" "+read-tp-hard" + +// RUN: %clang -target armv5t-linux -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv5_THREAD_POINTER_UNSUPP %s +// ARMv5_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv5 sub-architecture + +// RUN: %clang -target thumbv6-linux -mtp=cp15 -### -S %s 2>&1 | \ +// RUN: FileCheck -check-prefix=ARMv6_THREAD_POINTER_UNSUPP %s +// ARMv6_THREAD_POINTER_UNSUPP: hardware TLS register is not supported for the armv6 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 arm-linux -### -S %s -arch armv7 2>&1 | \ +// 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"