1e5dd7070Spatrick //===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick
9e5dd7070Spatrick #include "Hexagon.h"
10e5dd7070Spatrick #include "CommonArgs.h"
11e5dd7070Spatrick #include "clang/Driver/Compilation.h"
12e5dd7070Spatrick #include "clang/Driver/Driver.h"
13e5dd7070Spatrick #include "clang/Driver/DriverDiagnostic.h"
14a9ac8606Spatrick #include "clang/Driver/InputInfo.h"
15e5dd7070Spatrick #include "clang/Driver/Options.h"
16e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
17e5dd7070Spatrick #include "llvm/Option/ArgList.h"
18e5dd7070Spatrick #include "llvm/Support/FileSystem.h"
19e5dd7070Spatrick #include "llvm/Support/Path.h"
20e5dd7070Spatrick #include "llvm/Support/VirtualFileSystem.h"
21e5dd7070Spatrick
22e5dd7070Spatrick using namespace clang::driver;
23e5dd7070Spatrick using namespace clang::driver::tools;
24e5dd7070Spatrick using namespace clang::driver::toolchains;
25e5dd7070Spatrick using namespace clang;
26e5dd7070Spatrick using namespace llvm::opt;
27e5dd7070Spatrick
28e5dd7070Spatrick // Default hvx-length for various versions.
getDefaultHvxLength(StringRef HvxVer)29*12c85518Srobert static StringRef getDefaultHvxLength(StringRef HvxVer) {
30*12c85518Srobert return llvm::StringSwitch<StringRef>(HvxVer)
31e5dd7070Spatrick .Case("v60", "64b")
32e5dd7070Spatrick .Case("v62", "64b")
33e5dd7070Spatrick .Case("v65", "64b")
34e5dd7070Spatrick .Default("128b");
35e5dd7070Spatrick }
36e5dd7070Spatrick
handleHVXWarnings(const Driver & D,const ArgList & Args)37e5dd7070Spatrick static void handleHVXWarnings(const Driver &D, const ArgList &Args) {
38e5dd7070Spatrick // Handle the unsupported values passed to mhvx-length.
39e5dd7070Spatrick if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
40e5dd7070Spatrick StringRef Val = A->getValue();
41a9ac8606Spatrick if (!Val.equals_insensitive("64b") && !Val.equals_insensitive("128b"))
42e5dd7070Spatrick D.Diag(diag::err_drv_unsupported_option_argument)
43*12c85518Srobert << A->getSpelling() << Val;
44e5dd7070Spatrick }
45e5dd7070Spatrick }
46e5dd7070Spatrick
47e5dd7070Spatrick // Handle hvx target features explicitly.
handleHVXTargetFeatures(const Driver & D,const ArgList & Args,std::vector<StringRef> & Features,StringRef Cpu,bool & HasHVX)48e5dd7070Spatrick static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args,
49e5dd7070Spatrick std::vector<StringRef> &Features,
50ec727ea7Spatrick StringRef Cpu, bool &HasHVX) {
51e5dd7070Spatrick // Handle HVX warnings.
52e5dd7070Spatrick handleHVXWarnings(D, Args);
53e5dd7070Spatrick
54*12c85518Srobert auto makeFeature = [&Args](Twine T, bool Enable) -> StringRef {
55*12c85518Srobert const std::string &S = T.str();
56*12c85518Srobert StringRef Opt(S);
57*12c85518Srobert if (Opt.endswith("="))
58*12c85518Srobert Opt = Opt.drop_back(1);
59*12c85518Srobert if (Opt.startswith("mno-"))
60*12c85518Srobert Opt = Opt.drop_front(4);
61*12c85518Srobert else if (Opt.startswith("m"))
62*12c85518Srobert Opt = Opt.drop_front(1);
63*12c85518Srobert return Args.MakeArgString(Twine(Enable ? "+" : "-") + Twine(Opt));
64*12c85518Srobert };
65e5dd7070Spatrick
66*12c85518Srobert auto withMinus = [](StringRef S) -> std::string {
67*12c85518Srobert return "-" + S.str();
68*12c85518Srobert };
69*12c85518Srobert
70*12c85518Srobert // Drop tiny core suffix for HVX version.
71*12c85518Srobert std::string HvxVer =
72*12c85518Srobert (Cpu.back() == 'T' || Cpu.back() == 't' ? Cpu.drop_back(1) : Cpu).str();
73*12c85518Srobert HasHVX = false;
74*12c85518Srobert
75*12c85518Srobert // Handle -mhvx, -mhvx=, -mno-hvx. If versioned and versionless flags
76*12c85518Srobert // are both present, the last one wins.
77*12c85518Srobert Arg *HvxEnablingArg =
78*12c85518Srobert Args.getLastArg(options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ,
79*12c85518Srobert options::OPT_mno_hexagon_hvx);
80*12c85518Srobert if (HvxEnablingArg) {
81*12c85518Srobert if (HvxEnablingArg->getOption().matches(options::OPT_mno_hexagon_hvx))
82*12c85518Srobert HvxEnablingArg = nullptr;
83*12c85518Srobert }
84*12c85518Srobert
85*12c85518Srobert if (HvxEnablingArg) {
86*12c85518Srobert // If -mhvx[=] was given, it takes precedence.
87*12c85518Srobert if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx,
88e5dd7070Spatrick options::OPT_mhexagon_hvx_EQ)) {
89*12c85518Srobert // If the version was given, set HvxVer. Otherwise HvxVer
90*12c85518Srobert // will remain equal to the CPU version.
91*12c85518Srobert if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ))
92*12c85518Srobert HvxVer = StringRef(A->getValue()).lower();
93e5dd7070Spatrick }
94*12c85518Srobert HasHVX = true;
95*12c85518Srobert Features.push_back(makeFeature(Twine("hvx") + HvxVer, true));
96*12c85518Srobert } else if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx)) {
97*12c85518Srobert // If there was an explicit -mno-hvx, add -hvx to target features.
98*12c85518Srobert Features.push_back(makeFeature(A->getOption().getName(), false));
99e5dd7070Spatrick }
100e5dd7070Spatrick
101*12c85518Srobert StringRef HvxLen = getDefaultHvxLength(HvxVer);
102*12c85518Srobert
103e5dd7070Spatrick // Handle -mhvx-length=.
104e5dd7070Spatrick if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
105e5dd7070Spatrick // These flags are valid only if HVX in enabled.
106e5dd7070Spatrick if (!HasHVX)
107*12c85518Srobert D.Diag(diag::err_drv_needs_hvx) << withMinus(A->getOption().getName());
108e5dd7070Spatrick else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
109*12c85518Srobert HvxLen = A->getValue();
110e5dd7070Spatrick }
111e5dd7070Spatrick
112*12c85518Srobert if (HasHVX) {
113*12c85518Srobert StringRef L = makeFeature(Twine("hvx-length") + HvxLen.lower(), true);
114*12c85518Srobert Features.push_back(L);
115*12c85518Srobert }
116*12c85518Srobert
117*12c85518Srobert unsigned HvxVerNum;
118*12c85518Srobert // getAsInteger returns 'true' on error.
119*12c85518Srobert if (StringRef(HvxVer).drop_front(1).getAsInteger(10, HvxVerNum))
120*12c85518Srobert HvxVerNum = 0;
121*12c85518Srobert
122*12c85518Srobert // Handle HVX floating point flags.
123*12c85518Srobert auto checkFlagHvxVersion =
124*12c85518Srobert [&](auto FlagOn, auto FlagOff,
125*12c85518Srobert unsigned MinVerNum) -> std::optional<StringRef> {
126*12c85518Srobert // Return an std::optional<StringRef>:
127*12c85518Srobert // - std::nullopt indicates a verification failure, or that the flag was not
128*12c85518Srobert // present in Args.
129*12c85518Srobert // - Otherwise the returned value is that name of the feature to add
130*12c85518Srobert // to Features.
131*12c85518Srobert Arg *A = Args.getLastArg(FlagOn, FlagOff);
132*12c85518Srobert if (!A)
133*12c85518Srobert return std::nullopt;
134*12c85518Srobert
135*12c85518Srobert StringRef OptName = A->getOption().getName();
136*12c85518Srobert if (A->getOption().matches(FlagOff))
137*12c85518Srobert return makeFeature(OptName, false);
138*12c85518Srobert
139*12c85518Srobert if (!HasHVX) {
140*12c85518Srobert D.Diag(diag::err_drv_needs_hvx) << withMinus(OptName);
141*12c85518Srobert return std::nullopt;
142*12c85518Srobert }
143*12c85518Srobert if (HvxVerNum < MinVerNum) {
144*12c85518Srobert D.Diag(diag::err_drv_needs_hvx_version)
145*12c85518Srobert << withMinus(OptName) << ("v" + std::to_string(HvxVerNum));
146*12c85518Srobert return std::nullopt;
147*12c85518Srobert }
148*12c85518Srobert return makeFeature(OptName, true);
149*12c85518Srobert };
150*12c85518Srobert
151*12c85518Srobert if (auto F = checkFlagHvxVersion(options::OPT_mhexagon_hvx_qfloat,
152*12c85518Srobert options::OPT_mno_hexagon_hvx_qfloat, 68)) {
153*12c85518Srobert Features.push_back(*F);
154*12c85518Srobert }
155*12c85518Srobert if (auto F = checkFlagHvxVersion(options::OPT_mhexagon_hvx_ieee_fp,
156*12c85518Srobert options::OPT_mno_hexagon_hvx_ieee_fp, 68)) {
157*12c85518Srobert Features.push_back(*F);
158e5dd7070Spatrick }
159e5dd7070Spatrick }
160e5dd7070Spatrick
161e5dd7070Spatrick // Hexagon target features.
getHexagonTargetFeatures(const Driver & D,const ArgList & Args,std::vector<StringRef> & Features)162e5dd7070Spatrick void hexagon::getHexagonTargetFeatures(const Driver &D, const ArgList &Args,
163e5dd7070Spatrick std::vector<StringRef> &Features) {
164e5dd7070Spatrick handleTargetFeaturesGroup(Args, Features,
165e5dd7070Spatrick options::OPT_m_hexagon_Features_Group);
166e5dd7070Spatrick
167e5dd7070Spatrick bool UseLongCalls = false;
168e5dd7070Spatrick if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
169e5dd7070Spatrick options::OPT_mno_long_calls)) {
170e5dd7070Spatrick if (A->getOption().matches(options::OPT_mlong_calls))
171e5dd7070Spatrick UseLongCalls = true;
172e5dd7070Spatrick }
173e5dd7070Spatrick
174e5dd7070Spatrick Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls");
175e5dd7070Spatrick
176e5dd7070Spatrick bool HasHVX = false;
177ec727ea7Spatrick StringRef Cpu(toolchains::HexagonToolChain::GetTargetCPUVersion(Args));
178ec727ea7Spatrick // 't' in Cpu denotes tiny-core micro-architecture. For now, the co-processors
179ec727ea7Spatrick // have no dependency on micro-architecture.
180ec727ea7Spatrick const bool TinyCore = Cpu.contains('t');
181ec727ea7Spatrick
182ec727ea7Spatrick if (TinyCore)
183ec727ea7Spatrick Cpu = Cpu.take_front(Cpu.size() - 1);
184ec727ea7Spatrick
185ec727ea7Spatrick handleHVXTargetFeatures(D, Args, Features, Cpu, HasHVX);
186e5dd7070Spatrick
187e5dd7070Spatrick if (HexagonToolChain::isAutoHVXEnabled(Args) && !HasHVX)
188*12c85518Srobert D.Diag(diag::warn_drv_needs_hvx) << "auto-vectorization";
189e5dd7070Spatrick }
190e5dd7070Spatrick
191e5dd7070Spatrick // Hexagon tools start.
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const192e5dd7070Spatrick void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
193e5dd7070Spatrick ArgStringList &CmdArgs) const {
194e5dd7070Spatrick }
195e5dd7070Spatrick
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const196e5dd7070Spatrick void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
197e5dd7070Spatrick const InputInfo &Output,
198e5dd7070Spatrick const InputInfoList &Inputs,
199e5dd7070Spatrick const ArgList &Args,
200e5dd7070Spatrick const char *LinkingOutput) const {
201e5dd7070Spatrick claimNoWarnArgs(Args);
202e5dd7070Spatrick
203e5dd7070Spatrick auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
204e5dd7070Spatrick const Driver &D = HTC.getDriver();
205e5dd7070Spatrick ArgStringList CmdArgs;
206e5dd7070Spatrick
207e5dd7070Spatrick CmdArgs.push_back("--arch=hexagon");
208e5dd7070Spatrick
209e5dd7070Spatrick RenderExtraToolArgs(JA, CmdArgs);
210e5dd7070Spatrick
211e5dd7070Spatrick const char *AsName = "llvm-mc";
212e5dd7070Spatrick CmdArgs.push_back("-filetype=obj");
213e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(
214e5dd7070Spatrick "-mcpu=hexagon" +
215e5dd7070Spatrick toolchains::HexagonToolChain::GetTargetCPUVersion(Args)));
216e5dd7070Spatrick
217*12c85518Srobert addSanitizerRuntimes(HTC, Args, CmdArgs);
218*12c85518Srobert
219e5dd7070Spatrick if (Output.isFilename()) {
220e5dd7070Spatrick CmdArgs.push_back("-o");
221e5dd7070Spatrick CmdArgs.push_back(Output.getFilename());
222e5dd7070Spatrick } else {
223e5dd7070Spatrick assert(Output.isNothing() && "Unexpected output");
224e5dd7070Spatrick CmdArgs.push_back("-fsyntax-only");
225e5dd7070Spatrick }
226e5dd7070Spatrick
227*12c85518Srobert if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_ieee_fp,
228*12c85518Srobert options::OPT_mno_hexagon_hvx_ieee_fp)) {
229*12c85518Srobert if (A->getOption().matches(options::OPT_mhexagon_hvx_ieee_fp))
230*12c85518Srobert CmdArgs.push_back("-mhvx-ieee-fp");
231*12c85518Srobert }
232*12c85518Srobert
233e5dd7070Spatrick if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
234*12c85518Srobert CmdArgs.push_back(Args.MakeArgString("-gpsize=" + Twine(*G)));
235e5dd7070Spatrick }
236e5dd7070Spatrick
237e5dd7070Spatrick Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
238e5dd7070Spatrick
239e5dd7070Spatrick // Only pass -x if gcc will understand it; otherwise hope gcc
240e5dd7070Spatrick // understands the suffix correctly. The main use case this would go
241e5dd7070Spatrick // wrong in is for linker inputs if they happened to have an odd
242e5dd7070Spatrick // suffix; really the only way to get this to happen is a command
243e5dd7070Spatrick // like '-x foobar a.c' which will treat a.c like a linker input.
244e5dd7070Spatrick //
245e5dd7070Spatrick // FIXME: For the linker case specifically, can we safely convert
246e5dd7070Spatrick // inputs into '-Wl,' options?
247e5dd7070Spatrick for (const auto &II : Inputs) {
248e5dd7070Spatrick // Don't try to pass LLVM or AST inputs to a generic gcc.
249e5dd7070Spatrick if (types::isLLVMIR(II.getType()))
250e5dd7070Spatrick D.Diag(clang::diag::err_drv_no_linker_llvm_support)
251e5dd7070Spatrick << HTC.getTripleString();
252e5dd7070Spatrick else if (II.getType() == types::TY_AST)
253e5dd7070Spatrick D.Diag(clang::diag::err_drv_no_ast_support)
254e5dd7070Spatrick << HTC.getTripleString();
255e5dd7070Spatrick else if (II.getType() == types::TY_ModuleFile)
256e5dd7070Spatrick D.Diag(diag::err_drv_no_module_support)
257e5dd7070Spatrick << HTC.getTripleString();
258e5dd7070Spatrick
259e5dd7070Spatrick if (II.isFilename())
260e5dd7070Spatrick CmdArgs.push_back(II.getFilename());
261e5dd7070Spatrick else
262e5dd7070Spatrick // Don't render as input, we need gcc to do the translations.
263e5dd7070Spatrick // FIXME: What is this?
264e5dd7070Spatrick II.getInputArg().render(Args, CmdArgs);
265e5dd7070Spatrick }
266e5dd7070Spatrick
267e5dd7070Spatrick auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
268a9ac8606Spatrick C.addCommand(std::make_unique<Command>(JA, *this,
269a9ac8606Spatrick ResponseFileSupport::AtFileCurCP(),
270a9ac8606Spatrick Exec, CmdArgs, Inputs, Output));
271e5dd7070Spatrick }
272e5dd7070Spatrick
RenderExtraToolArgs(const JobAction & JA,ArgStringList & CmdArgs) const273e5dd7070Spatrick void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
274e5dd7070Spatrick ArgStringList &CmdArgs) const {
275e5dd7070Spatrick }
276e5dd7070Spatrick
277e5dd7070Spatrick static void
constructHexagonLinkArgs(Compilation & C,const JobAction & JA,const toolchains::HexagonToolChain & HTC,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,ArgStringList & CmdArgs,const char * LinkingOutput)278e5dd7070Spatrick constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
279e5dd7070Spatrick const toolchains::HexagonToolChain &HTC,
280e5dd7070Spatrick const InputInfo &Output, const InputInfoList &Inputs,
281e5dd7070Spatrick const ArgList &Args, ArgStringList &CmdArgs,
282e5dd7070Spatrick const char *LinkingOutput) {
283e5dd7070Spatrick
284e5dd7070Spatrick const Driver &D = HTC.getDriver();
285e5dd7070Spatrick
286e5dd7070Spatrick //----------------------------------------------------------------------------
287e5dd7070Spatrick //
288e5dd7070Spatrick //----------------------------------------------------------------------------
289e5dd7070Spatrick bool IsStatic = Args.hasArg(options::OPT_static);
290e5dd7070Spatrick bool IsShared = Args.hasArg(options::OPT_shared);
291e5dd7070Spatrick bool IsPIE = Args.hasArg(options::OPT_pie);
292e5dd7070Spatrick bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
293e5dd7070Spatrick bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
294e5dd7070Spatrick bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
295e5dd7070Spatrick bool UseG0 = false;
296e5dd7070Spatrick const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
297a9ac8606Spatrick bool UseLLD = (llvm::sys::path::filename(Exec).equals_insensitive("ld.lld") ||
298a9ac8606Spatrick llvm::sys::path::stem(Exec).equals_insensitive("ld.lld"));
299e5dd7070Spatrick bool UseShared = IsShared && !IsStatic;
300e5dd7070Spatrick StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);
301e5dd7070Spatrick
302*12c85518Srobert bool NeedsSanitizerDeps = addSanitizerRuntimes(HTC, Args, CmdArgs);
303*12c85518Srobert bool NeedsXRayDeps = addXRayRuntime(HTC, Args, CmdArgs);
304*12c85518Srobert
305e5dd7070Spatrick //----------------------------------------------------------------------------
306e5dd7070Spatrick // Silence warnings for various options
307e5dd7070Spatrick //----------------------------------------------------------------------------
308e5dd7070Spatrick Args.ClaimAllArgs(options::OPT_g_Group);
309e5dd7070Spatrick Args.ClaimAllArgs(options::OPT_emit_llvm);
310e5dd7070Spatrick Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
311e5dd7070Spatrick // handled somewhere else.
312e5dd7070Spatrick Args.ClaimAllArgs(options::OPT_static_libgcc);
313e5dd7070Spatrick
314e5dd7070Spatrick //----------------------------------------------------------------------------
315e5dd7070Spatrick //
316e5dd7070Spatrick //----------------------------------------------------------------------------
317e5dd7070Spatrick if (Args.hasArg(options::OPT_s))
318e5dd7070Spatrick CmdArgs.push_back("-s");
319e5dd7070Spatrick
320e5dd7070Spatrick if (Args.hasArg(options::OPT_r))
321e5dd7070Spatrick CmdArgs.push_back("-r");
322e5dd7070Spatrick
323e5dd7070Spatrick for (const auto &Opt : HTC.ExtraOpts)
324e5dd7070Spatrick CmdArgs.push_back(Opt.c_str());
325e5dd7070Spatrick
326e5dd7070Spatrick if (!UseLLD) {
327e5dd7070Spatrick CmdArgs.push_back("-march=hexagon");
328e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString("-mcpu=hexagon" + CpuVer));
329e5dd7070Spatrick }
330e5dd7070Spatrick
331e5dd7070Spatrick if (IsShared) {
332e5dd7070Spatrick CmdArgs.push_back("-shared");
333e5dd7070Spatrick // The following should be the default, but doing as hexagon-gcc does.
334e5dd7070Spatrick CmdArgs.push_back("-call_shared");
335e5dd7070Spatrick }
336e5dd7070Spatrick
337e5dd7070Spatrick if (IsStatic)
338e5dd7070Spatrick CmdArgs.push_back("-static");
339e5dd7070Spatrick
340e5dd7070Spatrick if (IsPIE && !IsShared)
341e5dd7070Spatrick CmdArgs.push_back("-pie");
342e5dd7070Spatrick
343e5dd7070Spatrick if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
344*12c85518Srobert CmdArgs.push_back(Args.MakeArgString("-G" + Twine(*G)));
345*12c85518Srobert UseG0 = *G == 0;
346e5dd7070Spatrick }
347e5dd7070Spatrick
348e5dd7070Spatrick CmdArgs.push_back("-o");
349e5dd7070Spatrick CmdArgs.push_back(Output.getFilename());
350e5dd7070Spatrick
351ec727ea7Spatrick if (HTC.getTriple().isMusl()) {
352ec727ea7Spatrick if (!Args.hasArg(options::OPT_shared, options::OPT_static))
353ec727ea7Spatrick CmdArgs.push_back("-dynamic-linker=/lib/ld-musl-hexagon.so.1");
354ec727ea7Spatrick
355ec727ea7Spatrick if (!Args.hasArg(options::OPT_shared, options::OPT_nostartfiles,
356ec727ea7Spatrick options::OPT_nostdlib))
357ec727ea7Spatrick CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/usr/lib/crt1.o"));
358ec727ea7Spatrick else if (Args.hasArg(options::OPT_shared) &&
359ec727ea7Spatrick !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib))
360ec727ea7Spatrick CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/usr/lib/crti.o"));
361ec727ea7Spatrick
362ec727ea7Spatrick CmdArgs.push_back(
363ec727ea7Spatrick Args.MakeArgString(StringRef("-L") + D.SysRoot + "/usr/lib"));
364ec727ea7Spatrick Args.AddAllArgs(CmdArgs,
365ec727ea7Spatrick {options::OPT_T_Group, options::OPT_e, options::OPT_s,
366ec727ea7Spatrick options::OPT_t, options::OPT_u_Group});
367ec727ea7Spatrick AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
368ec727ea7Spatrick
369ec727ea7Spatrick if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
370*12c85518Srobert if (NeedsSanitizerDeps) {
371*12c85518Srobert linkSanitizerRuntimeDeps(HTC, CmdArgs);
372*12c85518Srobert
373*12c85518Srobert CmdArgs.push_back("-lunwind");
374*12c85518Srobert }
375*12c85518Srobert if (NeedsXRayDeps)
376*12c85518Srobert linkXRayRuntimeDeps(HTC, CmdArgs);
377*12c85518Srobert
378ec727ea7Spatrick CmdArgs.push_back("-lclang_rt.builtins-hexagon");
379ec727ea7Spatrick CmdArgs.push_back("-lc");
380ec727ea7Spatrick }
381ec727ea7Spatrick if (D.CCCIsCXX()) {
382ec727ea7Spatrick if (HTC.ShouldLinkCXXStdlib(Args))
383ec727ea7Spatrick HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
384ec727ea7Spatrick }
385ec727ea7Spatrick return;
386ec727ea7Spatrick }
387ec727ea7Spatrick
388e5dd7070Spatrick //----------------------------------------------------------------------------
389e5dd7070Spatrick // moslib
390e5dd7070Spatrick //----------------------------------------------------------------------------
391e5dd7070Spatrick std::vector<std::string> OsLibs;
392e5dd7070Spatrick bool HasStandalone = false;
393e5dd7070Spatrick for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
394e5dd7070Spatrick A->claim();
395e5dd7070Spatrick OsLibs.emplace_back(A->getValue());
396e5dd7070Spatrick HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
397e5dd7070Spatrick }
398e5dd7070Spatrick if (OsLibs.empty()) {
399e5dd7070Spatrick OsLibs.push_back("standalone");
400e5dd7070Spatrick HasStandalone = true;
401e5dd7070Spatrick }
402e5dd7070Spatrick
403e5dd7070Spatrick //----------------------------------------------------------------------------
404e5dd7070Spatrick // Start Files
405e5dd7070Spatrick //----------------------------------------------------------------------------
406e5dd7070Spatrick const std::string MCpuSuffix = "/" + CpuVer.str();
407e5dd7070Spatrick const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
408e5dd7070Spatrick const std::string RootDir =
409e5dd7070Spatrick HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
410e5dd7070Spatrick const std::string StartSubDir =
411e5dd7070Spatrick "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
412e5dd7070Spatrick
413e5dd7070Spatrick auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
414e5dd7070Spatrick const char *Name) -> std::string {
415e5dd7070Spatrick std::string RelName = SubDir + Name;
416e5dd7070Spatrick std::string P = HTC.GetFilePath(RelName.c_str());
417e5dd7070Spatrick if (llvm::sys::fs::exists(P))
418e5dd7070Spatrick return P;
419e5dd7070Spatrick return RootDir + RelName;
420e5dd7070Spatrick };
421e5dd7070Spatrick
422e5dd7070Spatrick if (IncStdLib && IncStartFiles) {
423e5dd7070Spatrick if (!IsShared) {
424e5dd7070Spatrick if (HasStandalone) {
425e5dd7070Spatrick std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
426e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(Crt0SA));
427e5dd7070Spatrick }
428e5dd7070Spatrick std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
429e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(Crt0));
430e5dd7070Spatrick }
431e5dd7070Spatrick std::string Init = UseShared
432e5dd7070Spatrick ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
433e5dd7070Spatrick : Find(RootDir, StartSubDir, "/init.o");
434e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(Init));
435e5dd7070Spatrick }
436e5dd7070Spatrick
437e5dd7070Spatrick //----------------------------------------------------------------------------
438e5dd7070Spatrick // Library Search Paths
439e5dd7070Spatrick //----------------------------------------------------------------------------
440e5dd7070Spatrick const ToolChain::path_list &LibPaths = HTC.getFilePaths();
441e5dd7070Spatrick for (const auto &LibPath : LibPaths)
442e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
443e5dd7070Spatrick
444e5dd7070Spatrick //----------------------------------------------------------------------------
445e5dd7070Spatrick //
446e5dd7070Spatrick //----------------------------------------------------------------------------
447e5dd7070Spatrick Args.AddAllArgs(CmdArgs,
448e5dd7070Spatrick {options::OPT_T_Group, options::OPT_e, options::OPT_s,
449e5dd7070Spatrick options::OPT_t, options::OPT_u_Group});
450e5dd7070Spatrick
451e5dd7070Spatrick AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
452e5dd7070Spatrick
453e5dd7070Spatrick //----------------------------------------------------------------------------
454e5dd7070Spatrick // Libraries
455e5dd7070Spatrick //----------------------------------------------------------------------------
456e5dd7070Spatrick if (IncStdLib && IncDefLibs) {
457e5dd7070Spatrick if (D.CCCIsCXX()) {
458e5dd7070Spatrick if (HTC.ShouldLinkCXXStdlib(Args))
459e5dd7070Spatrick HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
460e5dd7070Spatrick CmdArgs.push_back("-lm");
461e5dd7070Spatrick }
462e5dd7070Spatrick
463e5dd7070Spatrick CmdArgs.push_back("--start-group");
464e5dd7070Spatrick
465e5dd7070Spatrick if (!IsShared) {
466e5dd7070Spatrick for (StringRef Lib : OsLibs)
467e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
468e5dd7070Spatrick CmdArgs.push_back("-lc");
469e5dd7070Spatrick }
470e5dd7070Spatrick CmdArgs.push_back("-lgcc");
471e5dd7070Spatrick
472e5dd7070Spatrick CmdArgs.push_back("--end-group");
473e5dd7070Spatrick }
474e5dd7070Spatrick
475e5dd7070Spatrick //----------------------------------------------------------------------------
476e5dd7070Spatrick // End files
477e5dd7070Spatrick //----------------------------------------------------------------------------
478e5dd7070Spatrick if (IncStdLib && IncStartFiles) {
479e5dd7070Spatrick std::string Fini = UseShared
480e5dd7070Spatrick ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
481e5dd7070Spatrick : Find(RootDir, StartSubDir, "/fini.o");
482e5dd7070Spatrick CmdArgs.push_back(Args.MakeArgString(Fini));
483e5dd7070Spatrick }
484e5dd7070Spatrick }
485e5dd7070Spatrick
ConstructJob(Compilation & C,const JobAction & JA,const InputInfo & Output,const InputInfoList & Inputs,const ArgList & Args,const char * LinkingOutput) const486e5dd7070Spatrick void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
487e5dd7070Spatrick const InputInfo &Output,
488e5dd7070Spatrick const InputInfoList &Inputs,
489e5dd7070Spatrick const ArgList &Args,
490e5dd7070Spatrick const char *LinkingOutput) const {
491e5dd7070Spatrick auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
492e5dd7070Spatrick
493e5dd7070Spatrick ArgStringList CmdArgs;
494e5dd7070Spatrick constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
495e5dd7070Spatrick LinkingOutput);
496e5dd7070Spatrick
497e5dd7070Spatrick const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
498a9ac8606Spatrick C.addCommand(std::make_unique<Command>(JA, *this,
499a9ac8606Spatrick ResponseFileSupport::AtFileCurCP(),
500a9ac8606Spatrick Exec, CmdArgs, Inputs, Output));
501e5dd7070Spatrick }
502e5dd7070Spatrick // Hexagon tools end.
503e5dd7070Spatrick
504e5dd7070Spatrick /// Hexagon Toolchain
505e5dd7070Spatrick
getHexagonTargetDir(const std::string & InstalledDir,const SmallVectorImpl<std::string> & PrefixDirs) const506e5dd7070Spatrick std::string HexagonToolChain::getHexagonTargetDir(
507e5dd7070Spatrick const std::string &InstalledDir,
508e5dd7070Spatrick const SmallVectorImpl<std::string> &PrefixDirs) const {
509e5dd7070Spatrick std::string InstallRelDir;
510e5dd7070Spatrick const Driver &D = getDriver();
511e5dd7070Spatrick
512e5dd7070Spatrick // Locate the rest of the toolchain ...
513e5dd7070Spatrick for (auto &I : PrefixDirs)
514e5dd7070Spatrick if (D.getVFS().exists(I))
515e5dd7070Spatrick return I;
516e5dd7070Spatrick
517e5dd7070Spatrick if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
518e5dd7070Spatrick return InstallRelDir;
519e5dd7070Spatrick
520e5dd7070Spatrick return InstalledDir;
521e5dd7070Spatrick }
522e5dd7070Spatrick
523*12c85518Srobert std::optional<unsigned>
getSmallDataThreshold(const ArgList & Args)524*12c85518Srobert HexagonToolChain::getSmallDataThreshold(const ArgList &Args) {
525e5dd7070Spatrick StringRef Gn = "";
526e5dd7070Spatrick if (Arg *A = Args.getLastArg(options::OPT_G)) {
527e5dd7070Spatrick Gn = A->getValue();
528e5dd7070Spatrick } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
529e5dd7070Spatrick options::OPT_fPIC)) {
530e5dd7070Spatrick Gn = "0";
531e5dd7070Spatrick }
532e5dd7070Spatrick
533e5dd7070Spatrick unsigned G;
534e5dd7070Spatrick if (!Gn.getAsInteger(10, G))
535e5dd7070Spatrick return G;
536e5dd7070Spatrick
537*12c85518Srobert return std::nullopt;
538*12c85518Srobert }
539*12c85518Srobert
getCompilerRTPath() const540*12c85518Srobert std::string HexagonToolChain::getCompilerRTPath() const {
541*12c85518Srobert SmallString<128> Dir(getDriver().SysRoot);
542*12c85518Srobert llvm::sys::path::append(Dir, "usr", "lib");
543*12c85518Srobert Dir += SelectedMultilib.gccSuffix();
544*12c85518Srobert return std::string(Dir.str());
545e5dd7070Spatrick }
546e5dd7070Spatrick
getHexagonLibraryPaths(const ArgList & Args,ToolChain::path_list & LibPaths) const547e5dd7070Spatrick void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
548e5dd7070Spatrick ToolChain::path_list &LibPaths) const {
549e5dd7070Spatrick const Driver &D = getDriver();
550e5dd7070Spatrick
551e5dd7070Spatrick //----------------------------------------------------------------------------
552e5dd7070Spatrick // -L Args
553e5dd7070Spatrick //----------------------------------------------------------------------------
554e5dd7070Spatrick for (Arg *A : Args.filtered(options::OPT_L))
555*12c85518Srobert llvm::append_range(LibPaths, A->getValues());
556e5dd7070Spatrick
557e5dd7070Spatrick //----------------------------------------------------------------------------
558e5dd7070Spatrick // Other standard paths
559e5dd7070Spatrick //----------------------------------------------------------------------------
560e5dd7070Spatrick std::vector<std::string> RootDirs;
561e5dd7070Spatrick std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
562e5dd7070Spatrick std::back_inserter(RootDirs));
563e5dd7070Spatrick
564e5dd7070Spatrick std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
565e5dd7070Spatrick D.PrefixDirs);
566*12c85518Srobert if (!llvm::is_contained(RootDirs, TargetDir))
567e5dd7070Spatrick RootDirs.push_back(TargetDir);
568e5dd7070Spatrick
569e5dd7070Spatrick bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
570e5dd7070Spatrick // Assume G0 with -shared.
571e5dd7070Spatrick bool HasG0 = Args.hasArg(options::OPT_shared);
572e5dd7070Spatrick if (auto G = getSmallDataThreshold(Args))
573*12c85518Srobert HasG0 = *G == 0;
574e5dd7070Spatrick
575e5dd7070Spatrick const std::string CpuVer = GetTargetCPUVersion(Args).str();
576e5dd7070Spatrick for (auto &Dir : RootDirs) {
577e5dd7070Spatrick std::string LibDir = Dir + "/hexagon/lib";
578e5dd7070Spatrick std::string LibDirCpu = LibDir + '/' + CpuVer;
579e5dd7070Spatrick if (HasG0) {
580e5dd7070Spatrick if (HasPIC)
581e5dd7070Spatrick LibPaths.push_back(LibDirCpu + "/G0/pic");
582e5dd7070Spatrick LibPaths.push_back(LibDirCpu + "/G0");
583e5dd7070Spatrick }
584e5dd7070Spatrick LibPaths.push_back(LibDirCpu);
585e5dd7070Spatrick LibPaths.push_back(LibDir);
586e5dd7070Spatrick }
587e5dd7070Spatrick }
588e5dd7070Spatrick
HexagonToolChain(const Driver & D,const llvm::Triple & Triple,const llvm::opt::ArgList & Args)589e5dd7070Spatrick HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
590e5dd7070Spatrick const llvm::opt::ArgList &Args)
591e5dd7070Spatrick : Linux(D, Triple, Args) {
592e5dd7070Spatrick const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
593e5dd7070Spatrick D.PrefixDirs);
594e5dd7070Spatrick
595e5dd7070Spatrick // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
596e5dd7070Spatrick // program paths
597e5dd7070Spatrick const std::string BinDir(TargetDir + "/bin");
598e5dd7070Spatrick if (D.getVFS().exists(BinDir))
599e5dd7070Spatrick getProgramPaths().push_back(BinDir);
600e5dd7070Spatrick
601e5dd7070Spatrick ToolChain::path_list &LibPaths = getFilePaths();
602e5dd7070Spatrick
603e5dd7070Spatrick // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
604e5dd7070Spatrick // 'elf' OS type, so the Linux paths are not appropriate. When we actually
605e5dd7070Spatrick // support 'linux' we'll need to fix this up
606e5dd7070Spatrick LibPaths.clear();
607e5dd7070Spatrick getHexagonLibraryPaths(Args, LibPaths);
608e5dd7070Spatrick }
609e5dd7070Spatrick
~HexagonToolChain()610e5dd7070Spatrick HexagonToolChain::~HexagonToolChain() {}
611e5dd7070Spatrick
AddCXXStdlibLibArgs(const ArgList & Args,ArgStringList & CmdArgs) const612ec727ea7Spatrick void HexagonToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
613ec727ea7Spatrick ArgStringList &CmdArgs) const {
614ec727ea7Spatrick CXXStdlibType Type = GetCXXStdlibType(Args);
615ec727ea7Spatrick switch (Type) {
616ec727ea7Spatrick case ToolChain::CST_Libcxx:
617ec727ea7Spatrick CmdArgs.push_back("-lc++");
618*12c85518Srobert if (Args.hasArg(options::OPT_fexperimental_library))
619*12c85518Srobert CmdArgs.push_back("-lc++experimental");
620ec727ea7Spatrick CmdArgs.push_back("-lc++abi");
621ec727ea7Spatrick CmdArgs.push_back("-lunwind");
622ec727ea7Spatrick break;
623ec727ea7Spatrick
624ec727ea7Spatrick case ToolChain::CST_Libstdcxx:
625ec727ea7Spatrick CmdArgs.push_back("-lstdc++");
626ec727ea7Spatrick break;
627ec727ea7Spatrick }
628ec727ea7Spatrick }
629ec727ea7Spatrick
buildAssembler() const630e5dd7070Spatrick Tool *HexagonToolChain::buildAssembler() const {
631e5dd7070Spatrick return new tools::hexagon::Assembler(*this);
632e5dd7070Spatrick }
633e5dd7070Spatrick
buildLinker() const634e5dd7070Spatrick Tool *HexagonToolChain::buildLinker() const {
635e5dd7070Spatrick return new tools::hexagon::Linker(*this);
636e5dd7070Spatrick }
637e5dd7070Spatrick
getOptimizationLevel(const llvm::opt::ArgList & DriverArgs) const638e5dd7070Spatrick unsigned HexagonToolChain::getOptimizationLevel(
639e5dd7070Spatrick const llvm::opt::ArgList &DriverArgs) const {
640e5dd7070Spatrick // Copied in large part from lib/Frontend/CompilerInvocation.cpp.
641e5dd7070Spatrick Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
642e5dd7070Spatrick if (!A)
643e5dd7070Spatrick return 0;
644e5dd7070Spatrick
645e5dd7070Spatrick if (A->getOption().matches(options::OPT_O0))
646e5dd7070Spatrick return 0;
647e5dd7070Spatrick if (A->getOption().matches(options::OPT_Ofast) ||
648e5dd7070Spatrick A->getOption().matches(options::OPT_O4))
649e5dd7070Spatrick return 3;
650e5dd7070Spatrick assert(A->getNumValues() != 0);
651e5dd7070Spatrick StringRef S(A->getValue());
652e5dd7070Spatrick if (S == "s" || S == "z" || S.empty())
653e5dd7070Spatrick return 2;
654e5dd7070Spatrick if (S == "g")
655e5dd7070Spatrick return 1;
656e5dd7070Spatrick
657e5dd7070Spatrick unsigned OptLevel;
658e5dd7070Spatrick if (S.getAsInteger(10, OptLevel))
659e5dd7070Spatrick return 0;
660e5dd7070Spatrick return OptLevel;
661e5dd7070Spatrick }
662e5dd7070Spatrick
addClangTargetOptions(const ArgList & DriverArgs,ArgStringList & CC1Args,Action::OffloadKind) const663e5dd7070Spatrick void HexagonToolChain::addClangTargetOptions(const ArgList &DriverArgs,
664e5dd7070Spatrick ArgStringList &CC1Args,
665e5dd7070Spatrick Action::OffloadKind) const {
666ec727ea7Spatrick
667ec727ea7Spatrick bool UseInitArrayDefault = getTriple().isMusl();
668ec727ea7Spatrick
669ec727ea7Spatrick if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
670ec727ea7Spatrick options::OPT_fno_use_init_array,
671ec727ea7Spatrick UseInitArrayDefault))
672ec727ea7Spatrick CC1Args.push_back("-fno-use-init-array");
673ec727ea7Spatrick
674e5dd7070Spatrick if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
675e5dd7070Spatrick CC1Args.push_back("-target-feature");
676e5dd7070Spatrick CC1Args.push_back("+reserved-r19");
677e5dd7070Spatrick }
678e5dd7070Spatrick if (isAutoHVXEnabled(DriverArgs)) {
679e5dd7070Spatrick CC1Args.push_back("-mllvm");
680e5dd7070Spatrick CC1Args.push_back("-hexagon-autohvx");
681e5dd7070Spatrick }
682e5dd7070Spatrick }
683e5dd7070Spatrick
AddClangSystemIncludeArgs(const ArgList & DriverArgs,ArgStringList & CC1Args) const684e5dd7070Spatrick void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
685e5dd7070Spatrick ArgStringList &CC1Args) const {
686a9ac8606Spatrick if (DriverArgs.hasArg(options::OPT_nostdinc))
687e5dd7070Spatrick return;
688e5dd7070Spatrick
689a9ac8606Spatrick const bool IsELF = !getTriple().isMusl() && !getTriple().isOSLinux();
690a9ac8606Spatrick const bool IsLinuxMusl = getTriple().isMusl() && getTriple().isOSLinux();
691a9ac8606Spatrick
692e5dd7070Spatrick const Driver &D = getDriver();
693a9ac8606Spatrick SmallString<128> ResourceDirInclude(D.ResourceDir);
694a9ac8606Spatrick if (!IsELF) {
695a9ac8606Spatrick llvm::sys::path::append(ResourceDirInclude, "include");
696a9ac8606Spatrick if (!DriverArgs.hasArg(options::OPT_nobuiltininc) &&
697a9ac8606Spatrick (!IsLinuxMusl || DriverArgs.hasArg(options::OPT_nostdlibinc)))
698a9ac8606Spatrick addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
699a9ac8606Spatrick }
700a9ac8606Spatrick if (DriverArgs.hasArg(options::OPT_nostdlibinc))
701a9ac8606Spatrick return;
702a9ac8606Spatrick
703a9ac8606Spatrick const bool HasSysRoot = !D.SysRoot.empty();
704a9ac8606Spatrick if (HasSysRoot) {
705ec727ea7Spatrick SmallString<128> P(D.SysRoot);
706a9ac8606Spatrick if (IsLinuxMusl)
707ec727ea7Spatrick llvm::sys::path::append(P, "usr/include");
708ec727ea7Spatrick else
709ec727ea7Spatrick llvm::sys::path::append(P, "include");
710a9ac8606Spatrick
711ec727ea7Spatrick addExternCSystemInclude(DriverArgs, CC1Args, P.str());
712a9ac8606Spatrick // LOCAL_INCLUDE_DIR
713a9ac8606Spatrick addSystemInclude(DriverArgs, CC1Args, P + "/usr/local/include");
714a9ac8606Spatrick // TOOL_INCLUDE_DIR
715a9ac8606Spatrick AddMultilibIncludeArgs(DriverArgs, CC1Args);
716ec727ea7Spatrick }
717ec727ea7Spatrick
718a9ac8606Spatrick if (!DriverArgs.hasArg(options::OPT_nobuiltininc) && IsLinuxMusl)
719a9ac8606Spatrick addSystemInclude(DriverArgs, CC1Args, ResourceDirInclude);
720a9ac8606Spatrick
721a9ac8606Spatrick if (HasSysRoot)
722a9ac8606Spatrick return;
723e5dd7070Spatrick std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
724e5dd7070Spatrick D.PrefixDirs);
725e5dd7070Spatrick addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
726e5dd7070Spatrick }
727e5dd7070Spatrick
addLibCxxIncludePaths(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args) const728ec727ea7Spatrick void HexagonToolChain::addLibCxxIncludePaths(
729ec727ea7Spatrick const llvm::opt::ArgList &DriverArgs,
730ec727ea7Spatrick llvm::opt::ArgStringList &CC1Args) const {
731ec727ea7Spatrick const Driver &D = getDriver();
732ec727ea7Spatrick if (!D.SysRoot.empty() && getTriple().isMusl())
733a9ac8606Spatrick addLibStdCXXIncludePaths(D.SysRoot + "/usr/include/c++/v1", "", "",
734ec727ea7Spatrick DriverArgs, CC1Args);
735a9ac8606Spatrick else if (getTriple().isMusl())
736a9ac8606Spatrick addLibStdCXXIncludePaths("/usr/include/c++/v1", "", "", DriverArgs,
737a9ac8606Spatrick CC1Args);
738ec727ea7Spatrick else {
739ec727ea7Spatrick std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
740a9ac8606Spatrick addLibStdCXXIncludePaths(TargetDir + "/hexagon/include/c++/v1", "", "",
741a9ac8606Spatrick DriverArgs, CC1Args);
742ec727ea7Spatrick }
743ec727ea7Spatrick }
addLibStdCxxIncludePaths(const llvm::opt::ArgList & DriverArgs,llvm::opt::ArgStringList & CC1Args) const744e5dd7070Spatrick void HexagonToolChain::addLibStdCxxIncludePaths(
745e5dd7070Spatrick const llvm::opt::ArgList &DriverArgs,
746e5dd7070Spatrick llvm::opt::ArgStringList &CC1Args) const {
747e5dd7070Spatrick const Driver &D = getDriver();
748e5dd7070Spatrick std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
749a9ac8606Spatrick addLibStdCXXIncludePaths(TargetDir + "/hexagon/include/c++", "", "",
750e5dd7070Spatrick DriverArgs, CC1Args);
751e5dd7070Spatrick }
752e5dd7070Spatrick
753e5dd7070Spatrick ToolChain::CXXStdlibType
GetCXXStdlibType(const ArgList & Args) const754e5dd7070Spatrick HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
755e5dd7070Spatrick Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
756ec727ea7Spatrick if (!A) {
757ec727ea7Spatrick if (getTriple().isMusl())
758ec727ea7Spatrick return ToolChain::CST_Libcxx;
759ec727ea7Spatrick else
760e5dd7070Spatrick return ToolChain::CST_Libstdcxx;
761ec727ea7Spatrick }
762e5dd7070Spatrick StringRef Value = A->getValue();
763ec727ea7Spatrick if (Value != "libstdc++" && Value != "libc++")
764e5dd7070Spatrick getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
765e5dd7070Spatrick
766ec727ea7Spatrick if (Value == "libstdc++")
767ec727ea7Spatrick return ToolChain::CST_Libstdcxx;
768ec727ea7Spatrick else if (Value == "libc++")
769ec727ea7Spatrick return ToolChain::CST_Libcxx;
770ec727ea7Spatrick else
771e5dd7070Spatrick return ToolChain::CST_Libstdcxx;
772e5dd7070Spatrick }
773e5dd7070Spatrick
isAutoHVXEnabled(const llvm::opt::ArgList & Args)774e5dd7070Spatrick bool HexagonToolChain::isAutoHVXEnabled(const llvm::opt::ArgList &Args) {
775e5dd7070Spatrick if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
776e5dd7070Spatrick options::OPT_fno_vectorize))
777e5dd7070Spatrick return A->getOption().matches(options::OPT_fvectorize);
778e5dd7070Spatrick return false;
779e5dd7070Spatrick }
780e5dd7070Spatrick
781e5dd7070Spatrick //
782e5dd7070Spatrick // Returns the default CPU for Hexagon. This is the default compilation target
783e5dd7070Spatrick // if no Hexagon processor is selected at the command-line.
784e5dd7070Spatrick //
GetDefaultCPU()785*12c85518Srobert StringRef HexagonToolChain::GetDefaultCPU() {
786e5dd7070Spatrick return "hexagonv60";
787e5dd7070Spatrick }
788e5dd7070Spatrick
GetTargetCPUVersion(const ArgList & Args)789*12c85518Srobert StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
790e5dd7070Spatrick Arg *CpuArg = nullptr;
791e5dd7070Spatrick if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
792e5dd7070Spatrick CpuArg = A;
793e5dd7070Spatrick
794e5dd7070Spatrick StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
795e5dd7070Spatrick if (CPU.startswith("hexagon"))
796e5dd7070Spatrick return CPU.substr(sizeof("hexagon") - 1);
797e5dd7070Spatrick return CPU;
798e5dd7070Spatrick }
799