1 //===--- Hexagon.cpp - Hexagon ToolChain Implementations --------*- C++ -*-===//
3 // 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
7 //===----------------------------------------------------------------------===//
10 #include "CommonArgs.h"
11 #include "InputInfo.h"
12 #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"
20 #include "llvm/Support/VirtualFileSystem.h"
22 using namespace clang::driver;
23 using namespace clang::driver::tools;
24 using namespace clang::driver::toolchains;
25 using namespace clang;
26 using namespace llvm::opt;
28 // Default hvx-length for various versions.
29 static StringRef getDefaultHvxLength(StringRef Cpu) {
30 return llvm::StringSwitch<StringRef>(Cpu)
37 static void handleHVXWarnings(const Driver &D, const ArgList &Args) {
38 // Handle the unsupported values passed to mhvx-length.
39 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
40 StringRef Val = A->getValue();
41 if (!Val.equals_lower("64b") && !Val.equals_lower("128b"))
42 D.Diag(diag::err_drv_unsupported_option_argument)
43 << A->getOption().getName() << Val;
47 // Handle hvx target features explicitly.
48 static void handleHVXTargetFeatures(const Driver &D, const ArgList &Args,
49 std::vector<StringRef> &Features,
50 StringRef Cpu, bool &HasHVX) {
51 // Handle HVX warnings.
52 handleHVXWarnings(D, Args);
54 // Add the +hvx* features based on commandline flags.
55 StringRef HVXFeature, HVXLength;
57 // Handle -mhvx, -mhvx=, -mno-hvx.
58 if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx,
59 options::OPT_mhexagon_hvx,
60 options::OPT_mhexagon_hvx_EQ)) {
61 if (A->getOption().matches(options::OPT_mno_hexagon_hvx))
63 if (A->getOption().matches(options::OPT_mhexagon_hvx_EQ)) {
65 HVXFeature = Cpu = A->getValue();
66 HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + HVXFeature.lower());
67 } else if (A->getOption().matches(options::OPT_mhexagon_hvx)) {
69 HVXFeature = Args.MakeArgString(llvm::Twine("+hvx") + Cpu);
71 Features.push_back(HVXFeature);
74 // Handle -mhvx-length=.
75 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
76 // These flags are valid only if HVX in enabled.
78 D.Diag(diag::err_drv_invalid_hvx_length);
79 else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
80 HVXLength = A->getValue();
82 // Default hvx-length based on Cpu.
84 HVXLength = getDefaultHvxLength(Cpu);
86 if (!HVXLength.empty()) {
88 Args.MakeArgString(llvm::Twine("+hvx-length") + HVXLength.lower());
89 Features.push_back(HVXFeature);
93 // Hexagon target features.
94 void hexagon::getHexagonTargetFeatures(const Driver &D, const ArgList &Args,
95 std::vector<StringRef> &Features) {
96 handleTargetFeaturesGroup(Args, Features,
97 options::OPT_m_hexagon_Features_Group);
99 bool UseLongCalls = false;
100 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
101 options::OPT_mno_long_calls)) {
102 if (A->getOption().matches(options::OPT_mlong_calls))
106 Features.push_back(UseLongCalls ? "+long-calls" : "-long-calls");
109 StringRef Cpu(toolchains::HexagonToolChain::GetTargetCPUVersion(Args));
110 // 't' in Cpu denotes tiny-core micro-architecture. For now, the co-processors
111 // have no dependency on micro-architecture.
112 const bool TinyCore = Cpu.contains('t');
115 Cpu = Cpu.take_front(Cpu.size() - 1);
117 handleHVXTargetFeatures(D, Args, Features, Cpu, HasHVX);
119 if (HexagonToolChain::isAutoHVXEnabled(Args) && !HasHVX)
120 D.Diag(diag::warn_drv_vectorize_needs_hvx);
123 // Hexagon tools start.
124 void hexagon::Assembler::RenderExtraToolArgs(const JobAction &JA,
125 ArgStringList &CmdArgs) const {
128 void hexagon::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
129 const InputInfo &Output,
130 const InputInfoList &Inputs,
132 const char *LinkingOutput) const {
133 claimNoWarnArgs(Args);
135 auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
136 const Driver &D = HTC.getDriver();
137 ArgStringList CmdArgs;
139 CmdArgs.push_back("--arch=hexagon");
141 RenderExtraToolArgs(JA, CmdArgs);
143 const char *AsName = "llvm-mc";
144 CmdArgs.push_back("-filetype=obj");
145 CmdArgs.push_back(Args.MakeArgString(
147 toolchains::HexagonToolChain::GetTargetCPUVersion(Args)));
149 if (Output.isFilename()) {
150 CmdArgs.push_back("-o");
151 CmdArgs.push_back(Output.getFilename());
153 assert(Output.isNothing() && "Unexpected output");
154 CmdArgs.push_back("-fsyntax-only");
157 if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
158 CmdArgs.push_back(Args.MakeArgString("-gpsize=" + Twine(G.getValue())));
161 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
163 // Only pass -x if gcc will understand it; otherwise hope gcc
164 // understands the suffix correctly. The main use case this would go
165 // wrong in is for linker inputs if they happened to have an odd
166 // suffix; really the only way to get this to happen is a command
167 // like '-x foobar a.c' which will treat a.c like a linker input.
169 // FIXME: For the linker case specifically, can we safely convert
170 // inputs into '-Wl,' options?
171 for (const auto &II : Inputs) {
172 // Don't try to pass LLVM or AST inputs to a generic gcc.
173 if (types::isLLVMIR(II.getType()))
174 D.Diag(clang::diag::err_drv_no_linker_llvm_support)
175 << HTC.getTripleString();
176 else if (II.getType() == types::TY_AST)
177 D.Diag(clang::diag::err_drv_no_ast_support)
178 << HTC.getTripleString();
179 else if (II.getType() == types::TY_ModuleFile)
180 D.Diag(diag::err_drv_no_module_support)
181 << HTC.getTripleString();
184 CmdArgs.push_back(II.getFilename());
186 // Don't render as input, we need gcc to do the translations.
187 // FIXME: What is this?
188 II.getInputArg().render(Args, CmdArgs);
191 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
192 C.addCommand(std::make_unique<Command>(
193 JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
196 void hexagon::Linker::RenderExtraToolArgs(const JobAction &JA,
197 ArgStringList &CmdArgs) const {
201 constructHexagonLinkArgs(Compilation &C, const JobAction &JA,
202 const toolchains::HexagonToolChain &HTC,
203 const InputInfo &Output, const InputInfoList &Inputs,
204 const ArgList &Args, ArgStringList &CmdArgs,
205 const char *LinkingOutput) {
207 const Driver &D = HTC.getDriver();
209 //----------------------------------------------------------------------------
211 //----------------------------------------------------------------------------
212 bool IsStatic = Args.hasArg(options::OPT_static);
213 bool IsShared = Args.hasArg(options::OPT_shared);
214 bool IsPIE = Args.hasArg(options::OPT_pie);
215 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
216 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
217 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
219 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
220 bool UseLLD = (llvm::sys::path::filename(Exec).equals_lower("ld.lld") ||
221 llvm::sys::path::stem(Exec).equals_lower("ld.lld"));
222 bool UseShared = IsShared && !IsStatic;
223 StringRef CpuVer = toolchains::HexagonToolChain::GetTargetCPUVersion(Args);
225 //----------------------------------------------------------------------------
226 // Silence warnings for various options
227 //----------------------------------------------------------------------------
228 Args.ClaimAllArgs(options::OPT_g_Group);
229 Args.ClaimAllArgs(options::OPT_emit_llvm);
230 Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
231 // handled somewhere else.
232 Args.ClaimAllArgs(options::OPT_static_libgcc);
234 //----------------------------------------------------------------------------
236 //----------------------------------------------------------------------------
237 if (Args.hasArg(options::OPT_s))
238 CmdArgs.push_back("-s");
240 if (Args.hasArg(options::OPT_r))
241 CmdArgs.push_back("-r");
243 for (const auto &Opt : HTC.ExtraOpts)
244 CmdArgs.push_back(Opt.c_str());
247 CmdArgs.push_back("-march=hexagon");
248 CmdArgs.push_back(Args.MakeArgString("-mcpu=hexagon" + CpuVer));
252 CmdArgs.push_back("-shared");
253 // The following should be the default, but doing as hexagon-gcc does.
254 CmdArgs.push_back("-call_shared");
258 CmdArgs.push_back("-static");
260 if (IsPIE && !IsShared)
261 CmdArgs.push_back("-pie");
263 if (auto G = toolchains::HexagonToolChain::getSmallDataThreshold(Args)) {
264 CmdArgs.push_back(Args.MakeArgString("-G" + Twine(G.getValue())));
265 UseG0 = G.getValue() == 0;
268 CmdArgs.push_back("-o");
269 CmdArgs.push_back(Output.getFilename());
271 if (HTC.getTriple().isMusl()) {
272 if (!Args.hasArg(options::OPT_shared, options::OPT_static))
273 CmdArgs.push_back("-dynamic-linker=/lib/ld-musl-hexagon.so.1");
275 if (!Args.hasArg(options::OPT_shared, options::OPT_nostartfiles,
276 options::OPT_nostdlib))
277 CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/usr/lib/crt1.o"));
278 else if (Args.hasArg(options::OPT_shared) &&
279 !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib))
280 CmdArgs.push_back(Args.MakeArgString(D.SysRoot + "/usr/lib/crti.o"));
283 Args.MakeArgString(StringRef("-L") + D.SysRoot + "/usr/lib"));
284 Args.AddAllArgs(CmdArgs,
285 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
286 options::OPT_t, options::OPT_u_Group});
287 AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
289 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
290 CmdArgs.push_back("-lclang_rt.builtins-hexagon");
291 CmdArgs.push_back("-lc");
294 if (HTC.ShouldLinkCXXStdlib(Args))
295 HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
300 //----------------------------------------------------------------------------
302 //----------------------------------------------------------------------------
303 std::vector<std::string> OsLibs;
304 bool HasStandalone = false;
305 for (const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
307 OsLibs.emplace_back(A->getValue());
308 HasStandalone = HasStandalone || (OsLibs.back() == "standalone");
310 if (OsLibs.empty()) {
311 OsLibs.push_back("standalone");
312 HasStandalone = true;
315 //----------------------------------------------------------------------------
317 //----------------------------------------------------------------------------
318 const std::string MCpuSuffix = "/" + CpuVer.str();
319 const std::string MCpuG0Suffix = MCpuSuffix + "/G0";
320 const std::string RootDir =
321 HTC.getHexagonTargetDir(D.InstalledDir, D.PrefixDirs) + "/";
322 const std::string StartSubDir =
323 "hexagon/lib" + (UseG0 ? MCpuG0Suffix : MCpuSuffix);
325 auto Find = [&HTC] (const std::string &RootDir, const std::string &SubDir,
326 const char *Name) -> std::string {
327 std::string RelName = SubDir + Name;
328 std::string P = HTC.GetFilePath(RelName.c_str());
329 if (llvm::sys::fs::exists(P))
331 return RootDir + RelName;
334 if (IncStdLib && IncStartFiles) {
337 std::string Crt0SA = Find(RootDir, StartSubDir, "/crt0_standalone.o");
338 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
340 std::string Crt0 = Find(RootDir, StartSubDir, "/crt0.o");
341 CmdArgs.push_back(Args.MakeArgString(Crt0));
343 std::string Init = UseShared
344 ? Find(RootDir, StartSubDir + "/pic", "/initS.o")
345 : Find(RootDir, StartSubDir, "/init.o");
346 CmdArgs.push_back(Args.MakeArgString(Init));
349 //----------------------------------------------------------------------------
350 // Library Search Paths
351 //----------------------------------------------------------------------------
352 const ToolChain::path_list &LibPaths = HTC.getFilePaths();
353 for (const auto &LibPath : LibPaths)
354 CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath));
356 //----------------------------------------------------------------------------
358 //----------------------------------------------------------------------------
359 Args.AddAllArgs(CmdArgs,
360 {options::OPT_T_Group, options::OPT_e, options::OPT_s,
361 options::OPT_t, options::OPT_u_Group});
363 AddLinkerInputs(HTC, Inputs, Args, CmdArgs, JA);
365 //----------------------------------------------------------------------------
367 //----------------------------------------------------------------------------
368 if (IncStdLib && IncDefLibs) {
370 if (HTC.ShouldLinkCXXStdlib(Args))
371 HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
372 CmdArgs.push_back("-lm");
375 CmdArgs.push_back("--start-group");
378 for (StringRef Lib : OsLibs)
379 CmdArgs.push_back(Args.MakeArgString("-l" + Lib));
380 CmdArgs.push_back("-lc");
382 CmdArgs.push_back("-lgcc");
384 CmdArgs.push_back("--end-group");
387 //----------------------------------------------------------------------------
389 //----------------------------------------------------------------------------
390 if (IncStdLib && IncStartFiles) {
391 std::string Fini = UseShared
392 ? Find(RootDir, StartSubDir + "/pic", "/finiS.o")
393 : Find(RootDir, StartSubDir, "/fini.o");
394 CmdArgs.push_back(Args.MakeArgString(Fini));
398 void hexagon::Linker::ConstructJob(Compilation &C, const JobAction &JA,
399 const InputInfo &Output,
400 const InputInfoList &Inputs,
402 const char *LinkingOutput) const {
403 auto &HTC = static_cast<const toolchains::HexagonToolChain&>(getToolChain());
405 ArgStringList CmdArgs;
406 constructHexagonLinkArgs(C, JA, HTC, Output, Inputs, Args, CmdArgs,
409 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
410 C.addCommand(std::make_unique<Command>(
411 JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
413 // Hexagon tools end.
415 /// Hexagon Toolchain
417 std::string HexagonToolChain::getHexagonTargetDir(
418 const std::string &InstalledDir,
419 const SmallVectorImpl<std::string> &PrefixDirs) const {
420 std::string InstallRelDir;
421 const Driver &D = getDriver();
423 // Locate the rest of the toolchain ...
424 for (auto &I : PrefixDirs)
425 if (D.getVFS().exists(I))
428 if (getVFS().exists(InstallRelDir = InstalledDir + "/../target"))
429 return InstallRelDir;
434 Optional<unsigned> HexagonToolChain::getSmallDataThreshold(
435 const ArgList &Args) {
437 if (Arg *A = Args.getLastArg(options::OPT_G)) {
439 } else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
440 options::OPT_fPIC)) {
445 if (!Gn.getAsInteger(10, G))
451 void HexagonToolChain::getHexagonLibraryPaths(const ArgList &Args,
452 ToolChain::path_list &LibPaths) const {
453 const Driver &D = getDriver();
455 //----------------------------------------------------------------------------
457 //----------------------------------------------------------------------------
458 for (Arg *A : Args.filtered(options::OPT_L))
459 for (const char *Value : A->getValues())
460 LibPaths.push_back(Value);
462 //----------------------------------------------------------------------------
463 // Other standard paths
464 //----------------------------------------------------------------------------
465 std::vector<std::string> RootDirs;
466 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
467 std::back_inserter(RootDirs));
469 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
471 if (llvm::find(RootDirs, TargetDir) == RootDirs.end())
472 RootDirs.push_back(TargetDir);
474 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
475 // Assume G0 with -shared.
476 bool HasG0 = Args.hasArg(options::OPT_shared);
477 if (auto G = getSmallDataThreshold(Args))
478 HasG0 = G.getValue() == 0;
480 const std::string CpuVer = GetTargetCPUVersion(Args).str();
481 for (auto &Dir : RootDirs) {
482 std::string LibDir = Dir + "/hexagon/lib";
483 std::string LibDirCpu = LibDir + '/' + CpuVer;
486 LibPaths.push_back(LibDirCpu + "/G0/pic");
487 LibPaths.push_back(LibDirCpu + "/G0");
489 LibPaths.push_back(LibDirCpu);
490 LibPaths.push_back(LibDir);
494 HexagonToolChain::HexagonToolChain(const Driver &D, const llvm::Triple &Triple,
495 const llvm::opt::ArgList &Args)
496 : Linux(D, Triple, Args) {
497 const std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
500 // Note: Generic_GCC::Generic_GCC adds InstalledDir and getDriver().Dir to
502 const std::string BinDir(TargetDir + "/bin");
503 if (D.getVFS().exists(BinDir))
504 getProgramPaths().push_back(BinDir);
506 ToolChain::path_list &LibPaths = getFilePaths();
508 // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
509 // 'elf' OS type, so the Linux paths are not appropriate. When we actually
510 // support 'linux' we'll need to fix this up
512 getHexagonLibraryPaths(Args, LibPaths);
515 HexagonToolChain::~HexagonToolChain() {}
517 void HexagonToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
518 ArgStringList &CmdArgs) const {
519 CXXStdlibType Type = GetCXXStdlibType(Args);
521 case ToolChain::CST_Libcxx:
522 CmdArgs.push_back("-lc++");
523 CmdArgs.push_back("-lc++abi");
524 CmdArgs.push_back("-lunwind");
527 case ToolChain::CST_Libstdcxx:
528 CmdArgs.push_back("-lstdc++");
533 Tool *HexagonToolChain::buildAssembler() const {
534 return new tools::hexagon::Assembler(*this);
537 Tool *HexagonToolChain::buildLinker() const {
538 return new tools::hexagon::Linker(*this);
541 unsigned HexagonToolChain::getOptimizationLevel(
542 const llvm::opt::ArgList &DriverArgs) const {
543 // Copied in large part from lib/Frontend/CompilerInvocation.cpp.
544 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
548 if (A->getOption().matches(options::OPT_O0))
550 if (A->getOption().matches(options::OPT_Ofast) ||
551 A->getOption().matches(options::OPT_O4))
553 assert(A->getNumValues() != 0);
554 StringRef S(A->getValue());
555 if (S == "s" || S == "z" || S.empty())
561 if (S.getAsInteger(10, OptLevel))
566 void HexagonToolChain::addClangTargetOptions(const ArgList &DriverArgs,
567 ArgStringList &CC1Args,
568 Action::OffloadKind) const {
570 bool UseInitArrayDefault = getTriple().isMusl();
572 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
573 options::OPT_fno_use_init_array,
574 UseInitArrayDefault))
575 CC1Args.push_back("-fno-use-init-array");
577 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
578 CC1Args.push_back("-target-feature");
579 CC1Args.push_back("+reserved-r19");
581 if (isAutoHVXEnabled(DriverArgs)) {
582 CC1Args.push_back("-mllvm");
583 CC1Args.push_back("-hexagon-autohvx");
587 void HexagonToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
588 ArgStringList &CC1Args) const {
589 if (DriverArgs.hasArg(options::OPT_nostdinc) ||
590 DriverArgs.hasArg(options::OPT_nostdlibinc))
593 const Driver &D = getDriver();
594 if (!D.SysRoot.empty()) {
595 SmallString<128> P(D.SysRoot);
596 if (getTriple().isMusl())
597 llvm::sys::path::append(P, "usr/include");
599 llvm::sys::path::append(P, "include");
600 addExternCSystemInclude(DriverArgs, CC1Args, P.str());
604 std::string TargetDir = getHexagonTargetDir(D.getInstalledDir(),
606 addExternCSystemInclude(DriverArgs, CC1Args, TargetDir + "/hexagon/include");
609 void HexagonToolChain::addLibCxxIncludePaths(
610 const llvm::opt::ArgList &DriverArgs,
611 llvm::opt::ArgStringList &CC1Args) const {
612 const Driver &D = getDriver();
613 if (!D.SysRoot.empty() && getTriple().isMusl())
614 addLibStdCXXIncludePaths(D.SysRoot + "/usr/include/c++/v1", "", "", "", "",
615 "", DriverArgs, CC1Args);
616 else if (getTriple().isMusl())
617 addLibStdCXXIncludePaths("/usr/include/c++/v1", "", "", "", "", "",
618 DriverArgs, CC1Args);
620 std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
621 addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++/v1", "", "", "",
622 "", DriverArgs, CC1Args);
625 void HexagonToolChain::addLibStdCxxIncludePaths(
626 const llvm::opt::ArgList &DriverArgs,
627 llvm::opt::ArgStringList &CC1Args) const {
628 const Driver &D = getDriver();
629 std::string TargetDir = getHexagonTargetDir(D.InstalledDir, D.PrefixDirs);
630 addLibStdCXXIncludePaths(TargetDir, "/hexagon/include/c++", "", "", "", "",
631 DriverArgs, CC1Args);
634 ToolChain::CXXStdlibType
635 HexagonToolChain::GetCXXStdlibType(const ArgList &Args) const {
636 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
638 if (getTriple().isMusl())
639 return ToolChain::CST_Libcxx;
641 return ToolChain::CST_Libstdcxx;
643 StringRef Value = A->getValue();
644 if (Value != "libstdc++" && Value != "libc++")
645 getDriver().Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
647 if (Value == "libstdc++")
648 return ToolChain::CST_Libstdcxx;
649 else if (Value == "libc++")
650 return ToolChain::CST_Libcxx;
652 return ToolChain::CST_Libstdcxx;
655 bool HexagonToolChain::isAutoHVXEnabled(const llvm::opt::ArgList &Args) {
656 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
657 options::OPT_fno_vectorize))
658 return A->getOption().matches(options::OPT_fvectorize);
663 // Returns the default CPU for Hexagon. This is the default compilation target
664 // if no Hexagon processor is selected at the command-line.
666 const StringRef HexagonToolChain::GetDefaultCPU() {
670 const StringRef HexagonToolChain::GetTargetCPUVersion(const ArgList &Args) {
671 Arg *CpuArg = nullptr;
672 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
675 StringRef CPU = CpuArg ? CpuArg->getValue() : GetDefaultCPU();
676 if (CPU.startswith("hexagon"))
677 return CPU.substr(sizeof("hexagon") - 1);