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 static const std::pair<options::ID, const char *> FixedRegs[] = {
794 {options::OPT_ffixed_r16,
"+reserved-r16"},
795 {options::OPT_ffixed_r17,
"+reserved-r17"},
796 {options::OPT_ffixed_r18,
"+reserved-r18"},
797 {options::OPT_ffixed_r19,
"+reserved-r19"},
798 {options::OPT_ffixed_r20,
"+reserved-r20"},
799 {options::OPT_ffixed_r21,
"+reserved-r21"},
800 {options::OPT_ffixed_r22,
"+reserved-r22"},
801 {options::OPT_ffixed_r23,
"+reserved-r23"},
802 {options::OPT_ffixed_r24,
"+reserved-r24"},
803 {options::OPT_ffixed_r25,
"+reserved-r25"},
804 {options::OPT_ffixed_r26,
"+reserved-r26"},
805 {options::OPT_ffixed_r27,
"+reserved-r27"},
806 {options::OPT_ffixed_r28,
"+reserved-r28"},
808 for (
const auto &[Opt,
Feature] : FixedRegs) {
809 if (DriverArgs.hasArg(Opt)) {
810 CC1Args.push_back(
"-target-feature");
815 CC1Args.push_back(
"-mllvm");
816 CC1Args.push_back(
"-hexagon-autohvx");
821 ArgStringList &CC1Args)
const {
822 if (DriverArgs.hasArg(options::OPT_nostdinc))
826 const bool UseBuiltins = !DriverArgs.hasArg(options::OPT_nobuiltininc);
829 llvm::sys::path::append(ResourceDirInclude,
"include");
832 if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) {
839 llvm::sys::path::append(LocalIncludeDir,
"usr",
"local",
"include");
848 const llvm::opt::ArgList &DriverArgs,
849 llvm::opt::ArgStringList &CC1Args)
const {
852 llvm::sys::path::append(Dir,
"c++",
"v1");
857 const llvm::opt::ArgList &DriverArgs,
858 llvm::opt::ArgStringList &CC1Args)
const {
861 llvm::sys::path::append(Dir,
"c++");
868 if (Args.getLastArg(options::OPT_rtlib_EQ))
878 if (Args.getLastArg(options::OPT_unwindlib_EQ))
887 Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
894 StringRef
Value = A->getValue();
895 if (
Value !=
"libstdc++" &&
Value !=
"libc++")
896 getDriver().
Diag(diag::err_drv_invalid_stdlib_name) << A->getAsString(Args);
898 if (
Value ==
"libstdc++")
900 else if (
Value ==
"libc++")
907 if (Arg *A = Args.getLastArg(options::OPT_fvectorize,
908 options::OPT_fno_vectorize))
909 return A->getOption().matches(options::OPT_fvectorize);
920 Arg *CpuArg =
nullptr;
921 if (Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
924 StringRef CPU = CpuArg ? CpuArg->getValue() :
GetDefaultCPU();
925 CPU.consume_front(
"hexagon");
929std::optional<std::string>
933 Arg *HvxEnablingArg =
934 Args.getLastArg(options::OPT_mhexagon_hvx, options::OPT_mhexagon_hvx_EQ,
935 options::OPT_mno_hexagon_hvx);
936 if (!HvxEnablingArg ||
937 HvxEnablingArg->getOption().matches(options::OPT_mno_hexagon_hvx))
942 if (!Cpu.empty() && (Cpu.back() ==
'T' || Cpu.back() ==
't'))
943 HvxVer = Cpu.drop_back(1).str();
947 if (HvxEnablingArg->getOption().matches(options::OPT_mhexagon_hvx_EQ))
948 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()