From: Strahinja Petrovic Date: Tue, 12 Sep 2017 10:40:58 +0000 (+0000) Subject: [ARM] Option for reading thread pointer from coprocessor register X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0810e2be8fa9a97519b8e3406e8f67645738c29b;p=clang [ARM] Option for reading thread pointer from coprocessor register This patch enables option for reading thread pointer directly from coprocessor register (-mtp=soft/cp15). Differential Revision: https://reviews.llvm.org/D34878 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313018 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index a076b02ea5..418d76ac2a 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -101,6 +101,10 @@ def err_drv_force_crash : Error< "failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">; def err_drv_invalid_mfloat_abi : Error< "invalid float ABI '%0'">; +def err_drv_invalid_mtp : Error< + "invalid thread pointer reading mode '%0'">; +def err_drv_missing_arg_mtp : Error< + "missing argument to '%0'">; def err_drv_invalid_libcxx_deployment : Error< "invalid deployment target for -stdlib=libc++ (requires %0 or later)">; def err_drv_invalid_argument_to_fdebug_prefix_map : Error< diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 74e4fb60ee..d73a34519f 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -257,6 +257,8 @@ def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, "precision">; def mfloat_abi : Separate<["-"], "mfloat-abi">, HelpText<"The float ABI to use">; +def mtp : Separate<["-"], "mtp">, + HelpText<"Mode for reading thread pointer">; def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, HelpText<"Limit float precision to the given value">; def split_stacks : Flag<["-"], "split-stacks">, diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 38b694fd5d..4f6cbe5fd4 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -1689,6 +1689,8 @@ def mexecute_only : Flag<["-"], "mexecute-only">, Group, HelpText<"Disallow generation of data access to code sections (ARM only)">; def mno_execute_only : Flag<["-"], "mno-execute-only">, Group, HelpText<"Allow generation of data access to code sections (ARM only)">; +def mtp_mode_EQ : Joined<["-"], "mtp=">, Group, Values<"soft, cp15">, + HelpText<"Read thread pointer from coprocessor register (ARM only)">; 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/lib/Driver/ToolChains/Arch/ARM.cpp b/lib/Driver/ToolChains/Arch/ARM.cpp index a5d63557f4..44c8871d0e 100644 --- a/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/lib/Driver/ToolChains/Arch/ARM.cpp @@ -131,6 +131,26 @@ bool arm::useAAPCSForMachO(const llvm::Triple &T) { T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T); } +// Select mode for reading thread pointer (-mtp=soft/cp15). +arm::ReadTPMode arm::getReadTPMode(const ToolChain &TC, const ArgList &Args) { + if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { + const Driver &D = TC.getDriver(); + arm::ReadTPMode ThreadPointer = + llvm::StringSwitch(A->getValue()) + .Case("cp15", ReadTPMode::Cp15) + .Case("soft", ReadTPMode::Soft) + .Default(ReadTPMode::Invalid); + if (ThreadPointer != ReadTPMode::Invalid) + return ThreadPointer; + if (StringRef(A->getValue()).empty()) + D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args); + else + D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); + return ReadTPMode::Invalid; + } + return ReadTPMode::Soft; +} + // Select the float ABI as determined by -msoft-float, -mhard-float, and // -mfloat-abi=. arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) { @@ -262,6 +282,7 @@ void arm::getARMTargetFeatures(const ToolChain &TC, bool KernelOrKext = Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext); arm::FloatABI ABI = arm::getARMFloatABI(TC, Args); + arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args); const Arg *WaCPU = nullptr, *WaFPU = nullptr; const Arg *WaHDiv = nullptr, *WaArch = nullptr; @@ -303,6 +324,9 @@ void arm::getARMTargetFeatures(const ToolChain &TC, } } + if (ThreadPointer == arm::ReadTPMode::Cp15) + Features.push_back("+read-tp-hard"); + // Check -march. ClangAs gives preference to -Wa,-march=. const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ); StringRef ArchName; diff --git a/lib/Driver/ToolChains/Arch/ARM.h b/lib/Driver/ToolChains/Arch/ARM.h index 52afaab762..c1dc168840 100644 --- a/lib/Driver/ToolChains/Arch/ARM.h +++ b/lib/Driver/ToolChains/Arch/ARM.h @@ -32,6 +32,12 @@ StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch, void appendEBLinkFlags(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple); +enum class ReadTPMode { + Invalid, + Soft, + Cp15, +}; + enum class FloatABI { Invalid, Soft, @@ -40,6 +46,7 @@ enum class FloatABI { }; FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args); +ReadTPMode getReadTPMode(const ToolChain &TC, const llvm::opt::ArgList &Args); bool useAAPCSForMachO(const llvm::Triple &T); void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args, diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c index 3b30f7af76..e563eddd3f 100644 --- a/test/Driver/clang-translation.c +++ b/test/Driver/clang-translation.c @@ -87,6 +87,18 @@ // ARMV5E: "-cc1" // ARMV5E: "-target-cpu" "arm1022e" +// RUN: %clang -target arm-linux -mtp=cp15 -### -S %s -arch armv7 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: 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: FileCheck -check-prefix=ARMv7_THREAD_POINTER_NON %s +// ARMv7_THREAD_POINTER_NON-NOT: "-target-feature" "+read-tp-hard" + // RUN: %clang -target powerpc64-unknown-linux-gnu \ // RUN: -### -S %s -mcpu=G5 2>&1 | FileCheck -check-prefix=PPCG5 %s // PPCG5: clang