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) {
417 llvm::sys::path::append(Crt0,
"crt0-semihost.o");
418 CmdArgs.push_back(Args.MakeArgString(Crt0));
422 llvm::sys::path::append(Crt0SA,
"crt0_standalone.o");
423 CmdArgs.push_back(Args.MakeArgString(Crt0SA));
426 llvm::sys::path::append(Crt0,
"crt0.o");
427 CmdArgs.push_back(Args.MakeArgString(Crt0));
432 llvm::sys::path::append(
Init, UseShared ?
"initS.o" :
"init.o");
433 CmdArgs.push_back(Args.MakeArgString(
Init));
441 for (
const auto &LibPath : LibPaths)
442 CmdArgs.push_back(Args.MakeArgString(StringRef(
"-L") + LibPath));
443 Args.ClaimAllArgs(options::OPT_L);
448 Args.addAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_s,
449 options::OPT_t, options::OPT_u_Group});
460 if (IncStdLib && IncDefLibs) {
464 CmdArgs.push_back(
"-lm");
467 CmdArgs.push_back(
"--start-group");
471 CmdArgs.push_back(
"-lsemihost");
473 for (StringRef Lib : OsLibs)
474 CmdArgs.push_back(Args.MakeArgString(
"-l" + Lib));
476 if (!Args.hasArg(options::OPT_nolibc))
477 CmdArgs.push_back(
"-lc");
481 CmdArgs.push_back(
"-lclang_rt.builtins");
483 CmdArgs.push_back(
"-lgcc");
485 CmdArgs.push_back(
"-lgcc");
488 CmdArgs.push_back(
"--end-group");
494 if (IncStdLib && IncStartFiles) {
497 llvm::sys::path::append(Fini, UseShared ?
"finiS.o" :
"fini.o");
498 CmdArgs.push_back(Args.MakeArgString(Fini));
507 const char *LinkingOutput)
const {
510 ArgStringList CmdArgs;
514 const char *Exec = Args.MakeArgString(HTC.GetLinkerPath());
515 C.addCommand(std::make_unique<Command>(JA, *
this,
517 Exec, CmdArgs, Inputs, Output));
524 const std::string &InstalledDir,
526 std::string InstallRelDir;
530 for (
auto &I : PrefixDirs)
531 if (D.getVFS().exists(I))
535 llvm::sys::path::append(Dir,
"..",
"target");
536 return std::string(Dir);
543 if (!D.SysRoot.empty())
556 llvm::sys::path::append(Dir,
"hexagon");
568 llvm::sys::path::append(Dir,
"usr",
"lib");
570 if (!IsLinuxMusl || !
getVFS().exists(Dir)) {
572 llvm::sys::path::append(Dir,
"lib");
575 llvm::sys::path::append(Dir, CpuVer);
578 llvm::sys::path::append(Dir,
"G0");
579 bool IsStatic = Args.hasArg(options::OPT_static);
580 bool IsShared = Args.hasArg(options::OPT_shared);
581 if (IsShared && !IsStatic)
582 llvm::sys::path::append(Dir,
"pic");
591 llvm::sys::path::append(Dir,
"usr",
"include");
593 if (!IsLinuxMusl || !
getVFS().exists(Dir)) {
595 llvm::sys::path::append(Dir,
"include");
599std::optional<unsigned>
602 if (Arg *A = Args.getLastArg(options::OPT_G)) {
604 }
else if (Args.getLastArg(options::OPT_shared, options::OPT_fpic,
605 options::OPT_fPIC)) {
610 if (!Gn.getAsInteger(10, G))
618 llvm::sys::path::append(Dir,
"usr",
"lib");
622 return std::string(Dir);
632 for (Arg *A : Args.filtered(options::OPT_L))
633 llvm::append_range(LibPaths, A->getValues());
638 std::vector<std::string> RootDirs;
639 std::copy(D.PrefixDirs.begin(), D.PrefixDirs.end(),
640 std::back_inserter(RootDirs));
643 if (!llvm::is_contained(RootDirs, SysRoot))
644 RootDirs.push_back(SysRoot);
646 bool HasPIC = Args.hasArg(options::OPT_fpic, options::OPT_fPIC);
648 bool HasG0 = Args.hasArg(options::OPT_shared);
653 for (
auto &Dir : RootDirs) {
654 std::string LibDir = Dir +
"/lib";
655 std::string LibDirCpu = LibDir +
'/' + CpuVer;
658 LibPaths.push_back(LibDirCpu +
"/G0/pic");
659 LibPaths.push_back(LibDirCpu +
"/G0");
661 LibPaths.push_back(LibDirCpu);
662 LibPaths.push_back(LibDir);
667 const llvm::opt::ArgList &Args)
668 :
Linux(D, Triple, Args) {
680 .
flag(
"-fsanitize=memory")
683 .
flag(
"-fsanitize=address")
698 llvm::sys::path::append(SanLibPath,
"usr",
"lib");
700 LibPaths.insert(LibPaths.begin(), std::string(SanLibPath));
709 ArgStringList &CmdArgs)
const {
713 const Arg *A = Args.getLastArg(options::OPT_unwindlib_EQ);
715 getDriver().
Diag(diag::err_drv_unsupported_unwind_for_platform)
716 << A->getValue() <<
getTriple().normalize();
723 CmdArgs.push_back(
"-lc++");
724 if (Args.hasArg(options::OPT_fexperimental_library))
725 CmdArgs.push_back(
"-lc++experimental");
726 CmdArgs.push_back(
"-lc++abi");
728 CmdArgs.push_back(
"-lunwind");
732 CmdArgs.push_back(
"-lstdc++");
746 const llvm::opt::ArgList &DriverArgs)
const {
748 Arg *A = DriverArgs.getLastArg(options::OPT_O_Group);
752 if (A->getOption().matches(options::OPT_O0))
754 if (A->getOption().matches(options::OPT_Ofast) ||
755 A->getOption().matches(options::OPT_O4))
757 assert(A->getNumValues() != 0);
758 StringRef S(A->getValue());
759 if (S ==
"s" || S ==
"z" || S.empty())
765 if (S.getAsInteger(10, OptLevel))
771 ArgStringList &CC1Args,
774 bool UseInitArrayDefault =
getTriple().isMusl();
776 if (!DriverArgs.hasFlag(options::OPT_fuse_init_array,
777 options::OPT_fno_use_init_array,
778 UseInitArrayDefault))
779 CC1Args.push_back(
"-fno-use-init-array");
781 if (DriverArgs.hasArg(options::OPT_ffixed_r19)) {
782 CC1Args.push_back(
"-target-feature");
783 CC1Args.push_back(
"+reserved-r19");
786 CC1Args.push_back(
"-mllvm");
787 CC1Args.push_back(
"-hexagon-autohvx");
792 ArgStringList &CC1Args)
const {
793 if (DriverArgs.hasArg(options::OPT_nostdinc))
797 const bool UseBuiltins = !DriverArgs.hasArg(options::OPT_nobuiltininc);
800 llvm::sys::path::append(ResourceDirInclude,
"include");
803 if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
810 llvm::sys::path::append(LocalIncludeDir,
"usr",
"local",
"include");
819 const llvm::opt::ArgList &DriverArgs,
820 llvm::opt::ArgStringList &CC1Args)
const {
823 llvm::sys::path::append(Dir,
"c++",
"v1");
828 const llvm::opt::ArgList &DriverArgs,
829 llvm::opt::ArgStringList &CC1Args)
const {
832 llvm::sys::path::append(Dir,
"c++");
839 if (Args.getLastArg(options::OPT_rtlib_EQ))
849 if (Args.getLastArg(options::OPT_unwindlib_EQ))
858 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
865 StringRef
Value = A->getValue();
866 if (
Value !=
"libstdc++" &&
Value !=
"libc++")
867 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
869 if (
Value ==
"libstdc++")
871 else if (
Value ==
"libc++")
878 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
879 options::OPT_fno_vectorize))
880 return A->getOption().matches(options::OPT_fvectorize);
891 Arg *CpuArg =
nullptr;
892 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
895 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
896 CPU.consume_front(
"hexagon");
900std::optional<std::string>
904 Arg *HvxEnablingArg =
905 Args.getLastArg(options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ,
906 options::OPT_mno_hexagon_hvx);
907 if (!HvxEnablingArg ||
908 HvxEnablingArg->getOption().matches(options::OPT_mno_hexagon_hvx))
913 if (!Cpu.empty() && (Cpu.back() ==
'T' || Cpu.back() ==
't'))
914 HvxVer = Cpu.drop_back(1).str();
918 if (HvxEnablingArg->getOption().matches(options::OPT_mhexagon_hvx_EQ))
919 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()