summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/CodeGenOptions.def3
-rw-r--r--clang/include/clang/Driver/Options.td3
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp1
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp13
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/test/Driver/tls-size.c26
6 files changed, 48 insertions, 0 deletions
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index cf8fbe251b3..50fc1836282 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -333,6 +333,9 @@ ENUM_CODEGENOPT(VecLib, VectorLibrary, 2, NoLibrary)
/// The default TLS model to use.
ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel)
+/// Bit size of immediate TLS offsets (0 == use the default).
+VALUE_CODEGENOPT(TLSSize, 8, 0)
+
/// Number of path components to strip when emitting checks. (0 == full
/// filename)
VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0)
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 0fee90707d4..71b257094a9 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2178,6 +2178,9 @@ def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=
def march_EQ : Joined<["-"], "march=">, Group<m_Group>, Flags<[CoreOption]>;
def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
+def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>, Flags<[DriverOption, CC1Option]>,
+ HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): "
+ "12 (for 4KB) | 24 (for 16MB, default) | 32 (for 4GB) | 48 (for 256TB, needs -mcmodel=large)">;
def mimplicit_it_EQ : Joined<["-"], "mimplicit-it=">, Group<m_Group>;
def mdefault_build_attributes : Joined<["-"], "mdefault-build-attributes">, Group<m_Group>;
def mno_default_build_attributes : Joined<["-"], "mno-default-build-attributes">, Group<m_Group>;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index d58bcf5a790..0bfcab88a3a 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -474,6 +474,7 @@ static void initTargetOptions(llvm::TargetOptions &Options,
Options.FunctionSections = CodeGenOpts.FunctionSections;
Options.DataSections = CodeGenOpts.DataSections;
Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
+ Options.TLSSize = CodeGenOpts.TLSSize;
Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
Options.ExplicitEmulatedTLS = CodeGenOpts.ExplicitEmulatedTLS;
Options.DebuggerTuning = CodeGenOpts.getDebuggerTuning();
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 4ef40e974cd..4d924e072f5 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -4531,6 +4531,19 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(A->getValue());
}
+ if (Arg *A = Args.getLastArg(options::OPT_mtls_size_EQ)) {
+ StringRef Value = A->getValue();
+ unsigned TLSSize = 0;
+ Value.getAsInteger(10, TLSSize);
+ if (!Triple.isAArch64() || !Triple.isOSBinFormatELF())
+ D.Diag(diag::err_drv_unsupported_opt_for_target)
+ << A->getOption().getName() << TripleStr;
+ if (TLSSize != 12 && TLSSize != 24 && TLSSize != 32 && TLSSize != 48)
+ D.Diag(diag::err_drv_invalid_int_value)
+ << A->getOption().getName() << Value;
+ Args.AddLastArg(CmdArgs, options::OPT_mtls_size_EQ);
+ }
+
// Add the target cpu
std::string CPU = getCPUName(Args, Triple, /*FromAs*/ false);
if (!CPU.empty()) {
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index c1841138741..4743d4f5809 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1268,6 +1268,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
}
}
+ Opts.TLSSize = getLastArgIntValue(Args, OPT_mtls_size_EQ, 0, Diags);
+
if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
StringRef Val = A->getValue();
Opts.FPDenormalMode = llvm::parseDenormalFPAttribute(Val);
diff --git a/clang/test/Driver/tls-size.c b/clang/test/Driver/tls-size.c
new file mode 100644
index 00000000000..7e94a91ccc8
--- /dev/null
+++ b/clang/test/Driver/tls-size.c
@@ -0,0 +1,26 @@
+// Options for AArch64 ELF
+// RUN: %clang -### -target aarch64-linux-gnu -mtls-size=12 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-12 %s
+// RUN: %clang -### -target aarch64-linux-gnu -mtls-size=24 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-24 %s
+// RUN: %clang -### -target aarch64-linux-gnu -mtls-size=32 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-32 %s
+// RUN: %clang -### -target aarch64-linux-gnu -mtls-size=48 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=CHECK-48 %s
+
+// Unsupported target
+// RUN: not %clang -target aarch64-unknown-windows-msvc -mtls-size=24 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=UNSUPPORTED-TARGET %s
+// RUN: not %clang -target x86_64-linux-gnu -mtls-size=24 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=UNSUPPORTED-TARGET %s
+
+// Invalid option value
+// RUN: not %clang -target aarch64-linux-gnu -mtls-size=0 %s 2>&1 \
+// RUN: | FileCheck -check-prefix=INVALID-VALUE %s
+
+// CHECK-12: "-cc1" {{.*}}"-mtls-size=12"
+// CHECK-24: "-cc1" {{.*}}"-mtls-size=24"
+// CHECK-32: "-cc1" {{.*}}"-mtls-size=32"
+// CHECK-48: "-cc1" {{.*}}"-mtls-size=48"
+// UNSUPPORTED-TARGET: error: unsupported option
+// INVALID-VALUE: error: invalid integral value
OpenPOWER on IntegriCloud