diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/CodeGenOptions.def | 3 | ||||
-rw-r--r-- | clang/include/clang/Driver/Options.td | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | clang/test/Driver/tls-size.c | 26 |
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 |