17#include "llvm/Option/ArgList.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/Path.h"
20#include "llvm/Support/VirtualFileSystem.h"
30 return llvm::StringSwitch<StringRef>(HvxVer)
39 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
40 StringRef Val = A->getValue();
41 if (!Val.equals_insensitive(
"64b") && !Val.equals_insensitive(
"128b"))
42 D.
Diag(diag::err_drv_unsupported_option_argument)
43 << A->getSpelling() << Val;
49 std::vector<StringRef> &Features,
50 StringRef Cpu,
bool &HasHVX) {
54 auto makeFeature = [&Args](Twine T,
bool Enable) -> StringRef {
55 const std::string &S = T.str();
57 Opt.consume_back(
"=");
58 if (Opt.starts_with(
"mno-"))
59 Opt = Opt.drop_front(4);
60 else if (Opt.starts_with(
"m"))
61 Opt = Opt.drop_front(1);
62 return Args.MakeArgString(Twine(Enable ?
"+" :
"-") + Twine(Opt));
65 auto withMinus = [](StringRef S) -> std::string {
69 std::optional<std::string> HvxVer =
71 HasHVX = HvxVer.has_value();
73 Features.push_back(makeFeature(Twine(
"hvx") + *HvxVer,
true));
75 if (Arg *A = Args.getLastArg(options::OPT_mno_hexagon_hvx)) {
77 Features.push_back(makeFeature(A->getOption().getName(),
false));
85 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_length_EQ)) {
88 D.
Diag(diag::err_drv_needs_hvx) << withMinus(A->getOption().getName());
89 else if (A->getOption().matches(options::OPT_mhexagon_hvx_length_EQ))
90 HvxLen = A->getValue();
94 StringRef L = makeFeature(Twine(
"hvx-length") + HvxLen.lower(),
true);
95 Features.push_back(L);
98 unsigned HvxVerNum = 0;
101 StringRef HvxVerRef(*HvxVer);
102 if (HvxVerRef.size() <= 1 ||
103 HvxVerRef.drop_front(1).getAsInteger(10, HvxVerNum))
108 auto checkFlagHvxVersion =
109 [&](
auto FlagOn,
auto FlagOff,
110 unsigned MinVerNum) -> std::optional<StringRef> {
116 Arg *A = Args.getLastArg(FlagOn, FlagOff);
120 StringRef OptName = A->getOption().getName();
121 if (A->getOption().matches(FlagOff))
122 return makeFeature(OptName,
false);
125 D.
Diag(diag::err_drv_needs_hvx) << withMinus(OptName);
128 if (HvxVerNum < MinVerNum) {
129 D.
Diag(diag::err_drv_needs_hvx_version)
130 << withMinus(OptName) << (
"v" + std::to_string(HvxVerNum));
133 return makeFeature(OptName,
true);
136 if (
auto F = checkFlagHvxVersion(options::OPT_mhexagon_hvx_qfloat,
137 options::OPT_mno_hexagon_hvx_qfloat, 68)) {
138 Features.push_back(*F);
140 if (
auto F = checkFlagHvxVersion(options::OPT_mhexagon_hvx_ieee_fp,
141 options::OPT_mno_hexagon_hvx_ieee_fp, 68)) {
142 Features.push_back(*F);
148 const llvm::Triple &Triple,
150 std::vector<StringRef> &Features) {
152 options::OPT_m_hexagon_Features_Group);
154 bool UseLongCalls =
false;
155 if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
156 options::OPT_mno_long_calls)) {
157 if (A->getOption().matches(options::OPT_mlong_calls))
161 Features.push_back(UseLongCalls ?
"+long-calls" :
"-long-calls");
167 const bool TinyCore = Cpu.contains(
't');
170 Cpu = Cpu.take_front(Cpu.size() - 1);
175 D.
Diag(diag::warn_drv_needs_hvx) <<
"auto-vectorization";
180 ArgStringList &CmdArgs)
const {
187 const char *LinkingOutput)
const {
191 const Driver &D = HTC.getDriver();
192 ArgStringList CmdArgs;
194 CmdArgs.push_back(
"--arch=hexagon");
198 const char *AsName =
"llvm-mc";
199 CmdArgs.push_back(
"-filetype=obj");
200 CmdArgs.push_back(Args.MakeArgString(
208 CmdArgs.push_back(
"-o");
211 CmdArgs.push_back(
"-fsyntax-only");
214 if (Arg *A = Args.getLastArg(options::OPT_mhexagon_hvx_ieee_fp,
215 options::OPT_mno_hexagon_hvx_ieee_fp)) {
216 if (A->getOption().matches(options::OPT_mhexagon_hvx_ieee_fp))
217 CmdArgs.push_back(
"-mhvx-ieee-fp");
221 CmdArgs.push_back(Args.MakeArgString(
"-gpsize=" + Twine(*G)));
224 Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
234 for (
const auto &II : Inputs) {
237 D.
Diag(clang::diag::err_drv_no_linker_llvm_support)
238 << HTC.getTripleString();
239 else if (II.getType() == types::TY_AST)
240 D.
Diag(clang::diag::err_drv_no_ast_support)
241 << HTC.getTripleString();
242 else if (II.getType() == types::TY_ModuleFile)
243 D.
Diag(diag::err_drv_no_module_support)
244 << HTC.getTripleString();
247 CmdArgs.push_back(II.getFilename());
251 II.getInputArg().render(Args, CmdArgs);
254 auto *Exec = Args.MakeArgString(HTC.GetProgramPath(AsName));
255 C.addCommand(std::make_unique<Command>(JA, *
this,
257 Exec, CmdArgs, Inputs, Output));
261 ArgStringList &CmdArgs)
const {
268 const ArgList &Args, ArgStringList &CmdArgs,
269 const char *LinkingOutput) {
276 bool IsStatic = Args.hasArg(options::OPT_static);
277 bool IsShared = Args.hasArg(options::OPT_shared);
278 bool IsPIE = Args.hasFlag(options::OPT_pie, options::OPT_no_pie,
280 bool IncStdLib = !Args.hasArg(options::OPT_nostdlib);
281 bool IncStartFiles = !Args.hasArg(options::OPT_nostartfiles);
282 bool IncDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
284 const char *Exec = Args.MakeArgString(HTC.
GetLinkerPath(&UseLLD));
285 UseLLD = UseLLD || llvm::sys::path::filename(Exec).ends_with(
"ld.lld") ||
286 llvm::sys::path::stem(Exec).ends_with(
"ld.lld");
287 bool UseShared = IsShared && !IsStatic;
296 Args.ClaimAllArgs(options::OPT_g_Group);
297 Args.ClaimAllArgs(options::OPT_emit_llvm);
298 Args.ClaimAllArgs(options::OPT_w);
300 Args.ClaimAllArgs(options::OPT_static_libgcc);
302 CmdArgs.push_back(
"--eh-frame-hdr");
306 if (Args.hasArg(options::OPT_s))
307 CmdArgs.push_back(
"-s");
309 if (Args.hasArg(options::OPT_r))
310 CmdArgs.push_back(
"-r");
313 CmdArgs.push_back(Opt.c_str());
316 CmdArgs.push_back(
"-march=hexagon");
317 CmdArgs.push_back(Args.MakeArgString(
"-mcpu=hexagon" + CpuVer));
321 CmdArgs.push_back(
"-shared");
323 CmdArgs.push_back(
"-call_shared");
327 CmdArgs.push_back(
"-static");
329 if (IsPIE && !IsShared && !Args.hasArg(options::OPT_r))
330 CmdArgs.push_back(
"-pie");
333 CmdArgs.push_back(Args.MakeArgString(
"-G" + Twine(*G)));
335 CmdArgs.push_back(
"-o");
339 if (!Args.hasArg(options::OPT_shared, options::OPT_static))
340 CmdArgs.push_back(
"-dynamic-linker=/lib/ld-musl-hexagon.so.1");
342 if (!Args.hasArg(options::OPT_shared, options::OPT_nostartfiles,
343 options::OPT_nostdlib))
344 CmdArgs.push_back(Args.MakeArgString(D.
SysRoot +
"/usr/lib/crt1.o"));
345 else if (Args.hasArg(options::OPT_shared) &&
346 !Args.hasArg(options::OPT_nostartfiles, options::OPT_nostdlib))
347 CmdArgs.push_back(Args.MakeArgString(D.
SysRoot +
"/usr/lib/crti.o"));
352 Args.MakeArgString(StringRef(
"-L") + D.
SysRoot +
"/usr/lib" +
356 Args.MakeArgString(StringRef(
"-L") + D.
SysRoot +
"/usr/lib"));
357 Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s,
358 options::OPT_t, options::OPT_u_Group});
367 if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
368 if (NeedsSanitizerDeps) {
372 CmdArgs.push_back(
"-lunwind");
377 if (!Args.hasArg(options::OPT_nolibc))
378 CmdArgs.push_back(
"-lc");
379 CmdArgs.push_back(
"-lclang_rt.builtins-hexagon");
386 for (
const auto &LibPath : LibPaths)
387 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
388 Args.ClaimAllArgs(options::OPT_L);
395 std::vector<std::string> OsLibs;
396 bool HasStandalone =
false;
397 for (
const Arg *A : Args.filtered(options::OPT_moslib_EQ)) {
399 OsLibs.emplace_back(A->getValue());
400 HasStandalone = HasStandalone || (OsLibs.back() ==
"standalone");
402 if (OsLibs.empty()) {
403 OsLibs.push_back(
"standalone");
404 HasStandalone =
true;
413 if (IncStdLib && IncStartFiles) {
418 llvm::sys::path::append(Crt0,
"crt0-noflash-hosted.o");
419 CmdArgs.push_back(Args.MakeArgString(Crt0));
420 }
else if (HTC.
getTriple().isOSUnknown()) {
421 llvm::sys::path::append(Crt0,
"crt0-semihost.o");
422 CmdArgs.push_back(Args.MakeArgString(Crt0));
428 llvm::sys::path::append(Crt0SA,
"crt0_standalone.o");
429 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
432 llvm::sys::path::append(Crt0,
"crt0.o");
433 CmdArgs.push_back(Args.MakeArgString(Crt0));
438 llvm::sys::path::append(
Init, UseShared ?
"initS.o" :
"init.o");
439 CmdArgs.push_back(Args.MakeArgString(
Init));
447 for (
const auto &LibPath : LibPaths)
448 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
449 Args.ClaimAllArgs(options::OPT_L);
454 Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s,
455 options::OPT_t, options::OPT_u_Group});
466 if (IncStdLib && IncDefLibs) {
470 CmdArgs.push_back(
"-lm");
473 CmdArgs.push_back(
"--start-group");
478 CmdArgs.push_back(
"-lh2");
479 CmdArgs.push_back(
"-lsyscall_wrapper");
480 }
else if (HTC.
getTriple().isOSUnknown()) {
481 CmdArgs.push_back(
"-lsemihost");
485 for (StringRef Lib : OsLibs)
486 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
488 if (!Args.hasArg(options::OPT_nolibc))
489 CmdArgs.push_back(
"-lc");
493 CmdArgs.push_back(
"-lclang_rt.builtins");
495 CmdArgs.push_back(
"-lgcc");
497 CmdArgs.push_back(
"-lgcc");
500 CmdArgs.push_back(
"--end-group");
506 if (IncStdLib && IncStartFiles) {
509 llvm::sys::path::append(Fini, UseShared ?
"finiS.o" :
"fini.o");
510 CmdArgs.push_back(Args.MakeArgString(Fini));
519 const char *LinkingOutput)
const {
522 ArgStringList CmdArgs;
526 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
527 C.addCommand(std::make_unique<Command>(JA, *
this,
529 Exec, CmdArgs, Inputs, Output));
536 const std::string &InstalledDir,
538 std::string InstallRelDir;
542 for (
auto &I : PrefixDirs)
543 if (D.getVFS().exists(I))
547 llvm::sys::path::append(Dir,
"..",
"target");
548 return std::string(Dir);
555 if (!D.SysRoot.empty())
568 llvm::sys::path::append(Dir,
"hexagon");
580 llvm::sys::path::append(Dir,
"usr",
"lib");
582 if (!IsLinuxMusl || !
getVFS().exists(Dir)) {
584 llvm::sys::path::append(Dir,
"lib");
587 llvm::sys::path::append(Dir, CpuVer);
590 llvm::sys::path::append(Dir,
"G0");
591 bool IsStatic = Args.hasArg(options::OPT_static);
592 bool IsShared = Args.hasArg(options::OPT_shared);
593 if (IsShared && !IsStatic)
594 llvm::sys::path::append(Dir,
"pic");
603 llvm::sys::path::append(Dir,
"usr",
"include");
605 if (!IsLinuxMusl || !
getVFS().exists(Dir)) {
607 llvm::sys::path::append(Dir,
"include");
611std::optional<unsigned>
614 if (Arg *A = Args.getLastArg(options::OPT_G)) {
616 }
else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
617 options::OPT_fPIC)) {
622 if (!Gn.getAsInteger(10, G))
630 llvm::sys::path::append(Dir,
"usr",
"lib");
634 return std::string(Dir);
644 for (Arg *A : Args.filtered(options::OPT_L))
645 llvm::append_range(LibPaths, A->getValues());
650 std::vector<std::string> RootDirs;
651 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
652 std::back_inserter(RootDirs));
655 if (!llvm::is_contained(RootDirs, SysRoot))
656 RootDirs.push_back(SysRoot);
658 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
660 bool HasG0 = Args.hasArg(options::OPT_shared);
665 for (
auto &Dir : RootDirs) {
666 std::string LibDir = Dir +
"/lib";
667 std::string LibDirCpu = LibDir +
'/' + CpuVer;
670 LibPaths.push_back(LibDirCpu +
"/G0/pic");
671 LibPaths.push_back(LibDirCpu +
"/G0");
673 LibPaths.push_back(LibDirCpu);
674 LibPaths.push_back(LibDir);
679 const llvm::opt::ArgList &Args)
680 :
Linux(D, Triple, Args) {
692 .
flag(
"-fsanitize=memory")
695 .
flag(
"-fsanitize=address")
710 llvm::sys::path::append(SanLibPath,
"usr",
"lib");
712 LibPaths.insert(LibPaths.begin(), std::string(SanLibPath));
721 ArgStringList &CmdArgs)
const {
725 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
727 getDriver().
Diag(diag::err_drv_unsupported_unwind_for_platform)
728 << A->getValue() <<
getTriple().normalize();
735 CmdArgs.push_back(
"-lc++");
736 if (Args.hasArg(options::OPT_fexperimental_library))
737 CmdArgs.push_back(
"-lc++experimental");
738 CmdArgs.push_back(
"-lc++abi");
740 CmdArgs.push_back(
"-lunwind");
744 CmdArgs.push_back(
"-lstdc++");
758 const llvm::opt::ArgList &DriverArgs)
const {
760 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
764 if (A->getOption().matches(options::OPT_O0))
766 if (A->getOption().matches(options::OPT_Ofast) ||
767 A->getOption().matches(options::OPT_O4))
769 assert(A->getNumValues() != 0);
770 StringRef S(A->getValue());
771 if (S ==
"s" || S ==
"z" || S.empty())
777 if (S.getAsInteger(10, OptLevel))
783 ArgStringList &CC1Args,
786 bool UseInitArrayDefault =
getTriple().isMusl();
788 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
789 options::OPT_fno_use_init_array,
790 UseInitArrayDefault))
791 CC1Args.push_back(
"-fno-use-init-array");
793 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
794 CC1Args.push_back(
"-target-feature");
795 CC1Args.push_back(
"+reserved-r19");
798 CC1Args.push_back(
"-mllvm");
799 CC1Args.push_back(
"-hexagon-autohvx");
804 ArgStringList &CC1Args)
const {
805 if (DriverArgs.hasArg(options::OPT_nostdinc))
809 const bool UseBuiltins = !DriverArgs.hasArg(options::OPT_nobuiltininc);
812 llvm::sys::path::append(ResourceDirInclude,
"include");
815 if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
822 llvm::sys::path::append(LocalIncludeDir,
"usr",
"local",
"include");
831 const llvm::opt::ArgList &DriverArgs,
832 llvm::opt::ArgStringList &CC1Args)
const {
835 llvm::sys::path::append(Dir,
"c++",
"v1");
840 const llvm::opt::ArgList &DriverArgs,
841 llvm::opt::ArgStringList &CC1Args)
const {
844 llvm::sys::path::append(Dir,
"c++");
851 if (Args.getLastArg(options::OPT_rtlib_EQ))
861 if (Args.getLastArg(options::OPT_unwindlib_EQ))
870 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
877 StringRef
Value = A->getValue();
878 if (
Value !=
"libstdc++" &&
Value !=
"libc++")
879 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
881 if (
Value ==
"libstdc++")
883 else if (
Value ==
"libc++")
890 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
891 options::OPT_fno_vectorize))
892 return A->getOption().matches(options::OPT_fvectorize);
903 Arg *CpuArg =
nullptr;
904 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
907 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
908 CPU.consume_front(
"hexagon");
912std::optional<std::string>
916 Arg *HvxEnablingArg =
917 Args.getLastArg(options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ,
918 options::OPT_mno_hexagon_hvx);
919 if (!HvxEnablingArg ||
920 HvxEnablingArg->getOption().matches(options::OPT_mno_hexagon_hvx))
925 if (!Cpu.empty() && (Cpu.back() ==
'T' || Cpu.back() ==
't'))
926 HvxVer = Cpu.drop_back(1).str();
930 if (HvxEnablingArg->getOption().matches(options::OPT_mhexagon_hvx_EQ))
931 HvxVer = StringRef(HvxEnablingArg->getValue()).lower();
static StringRef getTriple(const Command &Job)
The base class of the type hierarchy.
Compilation - A set of tasks to perform for a single driver invocation.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
std::string SysRoot
sysroot, if present
DiagnosticBuilder Diag(unsigned DiagID) const
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
LTOKind getLTOMode() const
Get the specific kind of LTO being performed.
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
This corresponds to a single GCC multilib, or a segment of one controlled by a command line flag.
MultilibBuilder & flag(StringRef Flag, bool Disallow=false)
Add a flag to the flags list Flag must be a flag accepted by the driver.
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
std::vector< std::string > flags_list
bool isLLVMIR(ID Id)
Is this LLVM IR.
SmallVector< InputInfo, 4 > InputInfoList
The JSON file list parser is used to communicate input to InstallAPI.
float __ovld __cnfn normalize(float)
Returns a vector in the same direction as p but with a length of 1.
static constexpr ResponseFileSupport AtFileCurCP()