blob: 5872d9b195cc20edffc58c2b78ea984cc6965772 [file] [log] [blame]
David L. Jonesf561aba2017-03-08 01:02:16 +00001//===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
David L. Jonesf561aba2017-03-08 01:02:16 +00006//
7//===----------------------------------------------------------------------===//
8
9#include "Hexagon.h"
David L. Jonesf561aba2017-03-08 01:02:16 +000010#include "CommonArgs.h"
Jonas Devliegherefc514902018-10-10 13:27:25 +000011#include "InputInfo.h"
David L. Jonesf561aba2017-03-08 01:02:16 +000012#include "clang/Driver/Compilation.h"
13#include "clang/Driver/Driver.h"
14#include "clang/Driver/DriverDiagnostic.h"
15#include "clang/Driver/Options.h"
16#include "llvm/ADT/StringExtras.h"
17#include "llvm/Option/ArgList.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/Path.h"
Jonas Devliegherefc514902018-10-10 13:27:25 +000020#include "llvm/Support/VirtualFileSystem.h"
David L. Jonesf561aba2017-03-08 01:02:16 +000021
22using namespace clang::driver;
23using namespace clang::driver::tools;
24using namespace clang::driver::toolchains;
25using namespace clang;
26using namespace llvm::opt;
27
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000028// Default hvx-length for various versions.
Benjamin Kramer2023e212017-10-18 21:43:42 +000029static StringRef getDefaultHvxLength(StringRef Cpu) {
30 return llvm::StringSwitch<StringRef>(Cpu)
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000031 .Case("v60", "64b")
32 .Case("v62", "64b")
Krzysztof Parzyszekcc5cd2c2017-12-13 13:48:07 +000033 .Case("v65", "64b")
Krzysztof Parzyszek85393b22018-12-05 21:38:35 +000034 .Case("v66", "128b")
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000035 .Default("128b");
36}
37
38static void handleHVXWarnings(const Driver &D, const ArgList &Args) {
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000039 // Handle the unsupported values passed to mhvx-length.
40 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
41 StringRef Val = A->getValue();
Krzysztof Parzyszek7c2031f2018-01-24 18:42:19 +000042 if (!Val.equals_lower("64b") && !Val.equals_lower("128b"))
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000043 D.Diag(diag::err_drv_unsupported_option_argument)
44 << A->getOption().getName() << Val;
45 }
46}
47
48// Handle hvx target features explicitly.
49static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args,
50 std::vector<StringRef> &Features,
51 bool &HasHVX) {
52 // Handle HVX warnings.
53 handleHVXWarnings(D, Args);
54
55 // Add the +hvx* features based on commandline flags.
56 StringRef HVXFeature, HVXLength;
57 StringRef Cpu(toolchains::HexagonToolChain::GetTargetCPUVersion(Args));
58
Krzysztof Parzyszek31636102018-04-03 15:59:10 +000059 // Handle -mhvx, -mhvx=, -mno-hvx.
60 if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx,
61 options::OPT_mhexagon_hvx,
62 options::OPT_mhexagon_hvx_EQ)) {
63 if (A->getOption().matches(options::OPT_mno_hexagon_hvx))
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000064 return;
Krzysztof Parzyszek31636102018-04-03 15:59:10 +000065 if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) {
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000066 HasHVX = true;
67 HVXFeature = Cpu = A->getValue();
68 HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + HVXFeature.lower());
69 } else if (A->getOption().matches(options::OPT_mhexagon_hvx)) {
70 HasHVX = true;
71 HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + Cpu);
72 }
73 Features.push_back(HVXFeature);
74 }
75
Krzysztof Parzyszek31636102018-04-03 15:59:10 +000076 // Handle -mhvx-length=.
77 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
Raphael Isemannb23ccec2018-12-10 12:37:46 +000078 // These flags are valid only if HVX in enabled.
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000079 if (!HasHVX)
80 D.Diag(diag::err_drv_invalid_hvx_length);
81 else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
82 HVXLength = A->getValue();
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000083 }
84 // Default hvx-length based on Cpu.
85 else if (HasHVX)
Benjamin Kramer2023e212017-10-18 21:43:42 +000086 HVXLength = getDefaultHvxLength(Cpu);
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000087
88 if (!HVXLength.empty()) {
89 HVXFeature =
90 Args.MakeArgString(llvm::Twine("+hvx-length") + HVXLength.lower());
91 Features.push_back(HVXFeature);
92 }
93}
94
Sumanth Gundapaneni2d9aa742017-10-04 19:09:29 +000095// Hexagon target features.
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +000096void hexagon::getHexagonTargetFeatures(const Driver &D, const ArgList &Args,
Sumanth Gundapaneni2d9aa742017-10-04 19:09:29 +000097 std::vector<StringRef> &Features) {
98 handleTargetFeaturesGroup(Args, Features,
99 options::OPT_m_hexagon_Features_Group);
100
101 bool UseLongCalls = false;
102 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
103 options::OPT_mno_long_calls)) {
104 if (A->getOption().matches(options::OPT_mlong_calls))
105 UseLongCalls = true;
106 }
107
108 Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls");
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +0000109
Krzysztof Parzyszek92ad94e2018-04-16 19:11:17 +0000110 bool HasHVX = false;
Sumanth Gundapaneni57098f52017-10-18 18:10:13 +0000111 handleHVXTargetFeatures(D, Args, Features, HasHVX);
Krzysztof Parzyszek92ad94e2018-04-16 19:11:17 +0000112
113 if (HexagonToolChain::isAutoHVXEnabled(Args) && !HasHVX)
114 D.Diag(diag::warn_drv_vectorize_needs_hvx);
Sumanth Gundapaneni2d9aa742017-10-04 19:09:29 +0000115}
116
David L. Jonesf561aba2017-03-08 01:02:16 +0000117// Hexagon tools start.
118void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
119 ArgStringList &CmdArgs) const {
120}
121
122void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
123 const InputInfo &Output,
124 const InputInfoList &Inputs,
125 const ArgList &Args,
126 const char *LinkingOutput) const {
127 claimNoWarnArgs(Args);
128
129 auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
130 const Driver &D = HTC.getDriver();
131 ArgStringList CmdArgs;
132
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000133 CmdArgs.push_back("-march=hexagon");
David L. Jonesf561aba2017-03-08 01:02:16 +0000134
135 RenderExtraToolArgs(JA, CmdArgs);
136
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000137 const char *AsName = "hexagon-llvm-mc";
David L. Jonesf561aba2017-03-08 01:02:16 +0000138 CmdArgs.push_back("-filetype=obj");
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000139 CmdArgs.push_back(Args.MakeArgString(
140 "-mcpu=hexagon" +
141 toolchains::HexagonToolChain::GetTargetCPUVersion(Args)));
David L. Jonesf561aba2017-03-08 01:02:16 +0000142
143 if (Output.isFilename()) {
144 CmdArgs.push_back("-o");
145 CmdArgs.push_back(Output.getFilename());
146 } else {
147 assert(Output.isNothing() && "Unexpected output");
148 CmdArgs.push_back("-fsyntax-only");
149 }
150
151 if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000152 CmdArgs.push_back(Args.MakeArgString("-gpsize=" + Twine(G.getValue())));
David L. Jonesf561aba2017-03-08 01:02:16 +0000153 }
154
155 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
156
157 // Only pass -x if gcc will understand it; otherwise hope gcc
158 // understands the suffix correctly. The main use case this would go
159 // wrong in is for linker inputs if they happened to have an odd
160 // suffix; really the only way to get this to happen is a command
161 // like '-x foobar a.c' which will treat a.c like a linker input.
162 //
163 // FIXME: For the linker case specifically, can we safely convert
164 // inputs into '-Wl,' options?
165 for (const auto &II : Inputs) {
166 // Don't try to pass LLVM or AST inputs to a generic gcc.
167 if (types::isLLVMIR(II.getType()))
168 D.Diag(clang::diag::err_drv_no_linker_llvm_support)
169 << HTC.getTripleString();
170 else if (II.getType() == types::TY_AST)
171 D.Diag(clang::diag::err_drv_no_ast_support)
172 << HTC.getTripleString();
173 else if (II.getType() == types::TY_ModuleFile)
174 D.Diag(diag::err_drv_no_module_support)
175 << HTC.getTripleString();
176
177 if (II.isFilename())
178 CmdArgs.push_back(II.getFilename());
179 else
180 // Don't render as input, we need gcc to do the translations.
181 // FIXME: What is this?
182 II.getInputArg().render(Args, CmdArgs);
183 }
184
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000185 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
David L. Jonesf561aba2017-03-08 01:02:16 +0000186 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
187}
188
189void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
190 ArgStringList &CmdArgs) const {
191}
192
193static void
194constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
195 const toolchains::HexagonToolChain &HTC,
196 const InputInfo &Output, const InputInfoList &Inputs,
197 const ArgList &Args, ArgStringList &CmdArgs,
198 const char *LinkingOutput) {
199
200 const Driver &D = HTC.getDriver();
201
202 //----------------------------------------------------------------------------
203 //
204 //----------------------------------------------------------------------------
205 bool IsStatic = Args.hasArg(options::OPT_static);
206 bool IsShared = Args.hasArg(options::OPT_shared);
207 bool IsPIE = Args.hasArg(options::OPT_pie);
208 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
209 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
210 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
211 bool UseG0 = false;
212 bool UseShared = IsShared && !IsStatic;
213
214 //----------------------------------------------------------------------------
215 // Silence warnings for various options
216 //----------------------------------------------------------------------------
217 Args.ClaimAllArgs(options::OPT_g_Group);
218 Args.ClaimAllArgs(options::OPT_emit_llvm);
219 Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
220 // handled somewhere else.
221 Args.ClaimAllArgs(options::OPT_static_libgcc);
222
223 //----------------------------------------------------------------------------
224 //
225 //----------------------------------------------------------------------------
226 if (Args.hasArg(options::OPT_s))
227 CmdArgs.push_back("-s");
228
229 if (Args.hasArg(options::OPT_r))
230 CmdArgs.push_back("-r");
231
232 for (const auto &Opt : HTC.ExtraOpts)
233 CmdArgs.push_back(Opt.c_str());
234
235 CmdArgs.push_back("-march=hexagon");
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000236 StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);
237 CmdArgs.push_back(Args.MakeArgString("-mcpu=hexagon" + CpuVer));
David L. Jonesf561aba2017-03-08 01:02:16 +0000238
239 if (IsShared) {
240 CmdArgs.push_back("-shared");
241 // The following should be the default, but doing as hexagon-gcc does.
242 CmdArgs.push_back("-call_shared");
243 }
244
245 if (IsStatic)
246 CmdArgs.push_back("-static");
247
248 if (IsPIE && !IsShared)
249 CmdArgs.push_back("-pie");
250
251 if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000252 CmdArgs.push_back(Args.MakeArgString("-G" + Twine(G.getValue())));
David L. Jonesf561aba2017-03-08 01:02:16 +0000253 UseG0 = G.getValue() == 0;
254 }
255
256 //----------------------------------------------------------------------------
257 //
258 //----------------------------------------------------------------------------
259 CmdArgs.push_back("-o");
260 CmdArgs.push_back(Output.getFilename());
261
262 //----------------------------------------------------------------------------
263 // moslib
264 //----------------------------------------------------------------------------
265 std::vector<std::string> OsLibs;
266 bool HasStandalone = false;
267
268 for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
269 A->claim();
270 OsLibs.emplace_back(A->getValue());
271 HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
272 }
273 if (OsLibs.empty()) {
274 OsLibs.push_back("standalone");
275 HasStandalone = true;
276 }
277
278 //----------------------------------------------------------------------------
279 // Start Files
280 //----------------------------------------------------------------------------
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000281 const std::string MCpuSuffix = "/" + CpuVer.str();
David L. Jonesf561aba2017-03-08 01:02:16 +0000282 const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
283 const std::string RootDir =
284 HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
285 const std::string StartSubDir =
286 "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
287
288 auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
289 const char *Name) -> std::string {
290 std::string RelName = SubDir + Name;
291 std::string P = HTC.GetFilePath(RelName.c_str());
292 if (llvm::sys::fs::exists(P))
293 return P;
294 return RootDir + RelName;
295 };
296
297 if (IncStdLib && IncStartFiles) {
298 if (!IsShared) {
299 if (HasStandalone) {
300 std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
301 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
302 }
303 std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
304 CmdArgs.push_back(Args.MakeArgString(Crt0));
305 }
306 std::string Init = UseShared
307 ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
308 : Find(RootDir, StartSubDir, "/init.o");
309 CmdArgs.push_back(Args.MakeArgString(Init));
310 }
311
312 //----------------------------------------------------------------------------
313 // Library Search Paths
314 //----------------------------------------------------------------------------
315 const ToolChain::path_list &LibPaths = HTC.getFilePaths();
316 for (const auto &LibPath : LibPaths)
317 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
318
319 //----------------------------------------------------------------------------
320 //
321 //----------------------------------------------------------------------------
322 Args.AddAllArgs(CmdArgs,
323 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
324 options::OPT_t, options::OPT_u_Group});
325
326 AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
327
328 //----------------------------------------------------------------------------
329 // Libraries
330 //----------------------------------------------------------------------------
331 if (IncStdLib && IncDefLibs) {
332 if (D.CCCIsCXX()) {
Nico Weber0ee47d92017-07-25 18:02:57 +0000333 if (HTC.ShouldLinkCXXStdlib(Args))
334 HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
David L. Jonesf561aba2017-03-08 01:02:16 +0000335 CmdArgs.push_back("-lm");
336 }
337
338 CmdArgs.push_back("--start-group");
339
340 if (!IsShared) {
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000341 for (StringRef Lib : OsLibs)
David L. Jonesf561aba2017-03-08 01:02:16 +0000342 CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
343 CmdArgs.push_back("-lc");
344 }
345 CmdArgs.push_back("-lgcc");
346
347 CmdArgs.push_back("--end-group");
348 }
349
350 //----------------------------------------------------------------------------
351 // End files
352 //----------------------------------------------------------------------------
353 if (IncStdLib && IncStartFiles) {
354 std::string Fini = UseShared
355 ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
356 : Find(RootDir, StartSubDir, "/fini.o");
357 CmdArgs.push_back(Args.MakeArgString(Fini));
358 }
359}
360
361void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
362 const InputInfo &Output,
363 const InputInfoList &Inputs,
364 const ArgList &Args,
365 const char *LinkingOutput) const {
366 auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
367
368 ArgStringList CmdArgs;
369 constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
370 LinkingOutput);
371
Sid Manninga6a20192018-10-10 15:37:03 +0000372 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
373 C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
David L. Jonesf561aba2017-03-08 01:02:16 +0000374}
375// Hexagon tools end.
376
377/// Hexagon Toolchain
378
379std::string HexagonToolChain::getHexagonTargetDir(
380 const std::string &InstalledDir,
381 const SmallVectorImpl<std::string> &PrefixDirs) const {
382 std::string InstallRelDir;
383 const Driver &D = getDriver();
384
385 // Locate the rest of the toolchain ...
386 for (auto &I : PrefixDirs)
387 if (D.getVFS().exists(I))
388 return I;
389
390 if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
391 return InstallRelDir;
392
393 return InstalledDir;
394}
395
396Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
397 const ArgList &Args) {
398 StringRef Gn = "";
399 if (Arg *A = Args.getLastArg(options::OPT_G)) {
400 Gn = A->getValue();
401 } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
402 options::OPT_fPIC)) {
403 Gn = "0";
404 }
405
406 unsigned G;
407 if (!Gn.getAsInteger(10, G))
408 return G;
409
410 return None;
411}
412
413void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
414 ToolChain::path_list &LibPaths) const {
415 const Driver &D = getDriver();
416
417 //----------------------------------------------------------------------------
418 // -L Args
419 //----------------------------------------------------------------------------
420 for (Arg *A : Args.filtered(options::OPT_L))
421 for (const char *Value : A->getValues())
422 LibPaths.push_back(Value);
423
424 //----------------------------------------------------------------------------
425 // Other standard paths
426 //----------------------------------------------------------------------------
427 std::vector<std::string> RootDirs;
428 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
429 std::back_inserter(RootDirs));
430
431 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
432 D.PrefixDirs);
Fangrui Song75e74e02019-03-31 08:48:19 +0000433 if (llvm::find(RootDirs, TargetDir) == RootDirs.end())
David L. Jonesf561aba2017-03-08 01:02:16 +0000434 RootDirs.push_back(TargetDir);
435
436 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
437 // Assume G0 with -shared.
438 bool HasG0 = Args.hasArg(options::OPT_shared);
439 if (auto G = getSmallDataThreshold(Args))
440 HasG0 = G.getValue() == 0;
441
442 const std::string CpuVer = GetTargetCPUVersion(Args).str();
443 for (auto &Dir : RootDirs) {
444 std::string LibDir = Dir + "/hexagon/lib";
445 std::string LibDirCpu = LibDir + '/' + CpuVer;
446 if (HasG0) {
447 if (HasPIC)
448 LibPaths.push_back(LibDirCpu + "/G0/pic");
449 LibPaths.push_back(LibDirCpu + "/G0");
450 }
451 LibPaths.push_back(LibDirCpu);
452 LibPaths.push_back(LibDir);
453 }
454}
455
456HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
457 const llvm::opt::ArgList &Args)
458 : Linux(D, Triple, Args) {
459 const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
460 D.PrefixDirs);
461
462 // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
463 // program paths
464 const std::string BinDir(TargetDir + "/bin");
465 if (D.getVFS().exists(BinDir))
466 getProgramPaths().push_back(BinDir);
467
468 ToolChain::path_list &LibPaths = getFilePaths();
469
470 // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
471 // 'elf' OS type, so the Linux paths are not appropriate. When we actually
472 // support 'linux' we'll need to fix this up
473 LibPaths.clear();
474 getHexagonLibraryPaths(Args, LibPaths);
475}
476
477HexagonToolChain::~HexagonToolChain() {}
478
479Tool *HexagonToolChain::buildAssembler() const {
480 return new tools::hexagon::Assembler(*this);
481}
482
483Tool *HexagonToolChain::buildLinker() const {
484 return new tools::hexagon::Linker(*this);
485}
486
Krzysztof Parzyszekdcda9452017-04-25 20:51:51 +0000487unsigned HexagonToolChain::getOptimizationLevel(
488 const llvm::opt::ArgList &DriverArgs) const {
489 // Copied in large part from lib/Frontend/CompilerInvocation.cpp.
490 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
491 if (!A)
492 return 0;
493
494 if (A->getOption().matches(options::OPT_O0))
495 return 0;
Krzysztof Parzyszekd6d41272017-04-25 21:31:55 +0000496 if (A->getOption().matches(options::OPT_Ofast) ||
497 A->getOption().matches(options::OPT_O4))
Krzysztof Parzyszekdcda9452017-04-25 20:51:51 +0000498 return 3;
499 assert(A->getNumValues() != 0);
500 StringRef S(A->getValue());
501 if (S == "s" || S == "z" || S.empty())
502 return 2;
503 if (S == "g")
504 return 1;
505
506 unsigned OptLevel;
507 if (S.getAsInteger(10, OptLevel))
508 return 0;
509 return OptLevel;
510}
511
512void HexagonToolChain::addClangTargetOptions(const ArgList &DriverArgs,
Gheorghe-Teodor Berceaf0f29602017-07-06 16:22:21 +0000513 ArgStringList &CC1Args,
514 Action::OffloadKind) const {
Krzysztof Parzyszekfde8b042018-02-28 20:31:55 +0000515 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
516 CC1Args.push_back("-target-feature");
517 CC1Args.push_back("+reserved-r19");
518 }
Alina Sbirlead981cc82018-10-27 04:51:09 +0000519 if (isAutoHVXEnabled(DriverArgs)) {
Krzysztof Parzyszek92ad94e2018-04-16 19:11:17 +0000520 CC1Args.push_back("-mllvm");
Alina Sbirlead981cc82018-10-27 04:51:09 +0000521 CC1Args.push_back("-hexagon-autohvx");
Krzysztof Parzyszeke4b0b6e2018-04-12 16:25:35 +0000522 }
Krzysztof Parzyszekdcda9452017-04-25 20:51:51 +0000523}
524
David L. Jonesf561aba2017-03-08 01:02:16 +0000525void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
526 ArgStringList &CC1Args) const {
527 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
528 DriverArgs.hasArg(options::OPT_nostdlibinc))
529 return;
530
531 const Driver &D = getDriver();
532 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
533 D.PrefixDirs);
534 addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
535}
536
537
538void HexagonToolChain::addLibStdCxxIncludePaths(
539 const llvm::opt::ArgList &DriverArgs,
540 llvm::opt::ArgStringList &CC1Args) const {
541 const Driver &D = getDriver();
542 std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
543 addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "",
544 DriverArgs, CC1Args);
545}
546
547ToolChain::CXXStdlibType
548HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
549 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
550 if (!A)
551 return ToolChain::CST_Libstdcxx;
552
553 StringRef Value = A->getValue();
554 if (Value != "libstdc++")
555 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
556
557 return ToolChain::CST_Libstdcxx;
558}
559
Krzysztof Parzyszek92ad94e2018-04-16 19:11:17 +0000560bool HexagonToolChain::isAutoHVXEnabled(const llvm::opt::ArgList &Args) {
561 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
562 options::OPT_fno_vectorize))
563 return A->getOption().matches(options::OPT_fvectorize);
564 return false;
565}
566
David L. Jonesf561aba2017-03-08 01:02:16 +0000567//
568// Returns the default CPU for Hexagon. This is the default compilation target
569// if no Hexagon processor is selected at the command-line.
570//
571const StringRef HexagonToolChain::GetDefaultCPU() {
572 return "hexagonv60";
573}
574
575const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
576 Arg *CpuArg = nullptr;
577 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ, options::OPT_march_EQ))
578 CpuArg = A;
579
580 StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
581 if (CPU.startswith("hexagon"))
582 return CPU.substr(sizeof("hexagon") - 1);
583 return CPU;
584}