[cfe-commits] [PATCH] Update Hexagon ToolChain (call linker directly, addl args, , etc)
Matthew Curtis
mcurtis at codeaurora.org
Thu Sep 6 14:24:54 PDT 2012
Hello all,
This patch updates the Hexagon ToolChain:
- reimplement hexagon::Link::ConstructJob to call linker directly
rather than going through gcc
- add/improve support for small data threshold, pic, and other args
- add overrides for include paths, et. al.
- minor refactoring
Please let me know if there are any problems or concerns. Thanks.
Cheers,
Matthew Curtis.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
-------------- next part --------------
>From 47657c0ed85dcff6c740959879dd2f154834f115 Mon Sep 17 00:00:00 2001
From: Matthew Curtis <mcurtis at codeaurora.org>
Date: Thu, 30 Aug 2012 11:46:24 -0500
Subject: [PATCH] Update Hexagon ToolChain (call linker directly, addl args,
etc)
- reimplement hexagon::Link::ConstructJob to call linker directly
rather than going through gcc
- add/improve support for small data threshold, pic, and other args
- add overrides for include paths et. al.
- minor refactoring
---
include/clang/Driver/Options.td | 5 +-
lib/Driver/Driver.cpp | 2 +-
lib/Driver/ToolChains.cpp | 206 +++++++++++++++++++++++++-
lib/Driver/ToolChains.h | 45 ++++--
lib/Driver/Tools.cpp | 305 ++++++++++++++++++++++++++-------------
5 files changed, 437 insertions(+), 126 deletions(-)
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index c7698a2..6f2f98a 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -158,7 +158,8 @@ def E : Flag<"-E">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>,
HelpText<"Only run the preprocessor">;
def F : JoinedOrSeparate<"-F">, Flags<[RenderJoined,CC1Option]>,
HelpText<"Add directory to framework include search path">;
-def G : Separate<"-G">, Flags<[DriverOption]>;
+def G : JoinedOrSeparate<"-G">, Flags<[DriverOption]>;
+def G_EQ : Joined<"-G=">, Flags<[DriverOption]>;
def H : Flag<"-H">, Flags<[CC1Option]>,
HelpText<"Show header includes and nesting depth">;
def I_ : Flag<"-I-">, Group<I_Group>;
@@ -830,6 +831,7 @@ def mno_warn_nonportable_cfstrings : Flag<"-mno-warn-nonportable-cfstrings">, Gr
def mno_omit_leaf_frame_pointer : Flag<"-mno-omit-leaf-frame-pointer">, Group<f_Group>;
def momit_leaf_frame_pointer : Flag<"-momit-leaf-frame-pointer">, Group<f_Group>,
HelpText<"Omit frame pointer setup for leaf functions.">, Flags<[CC1Option]>;
+def moslib_EQ : Joined<"-moslib=">, Group<m_Group>;
def mpascal_strings : Flag<"-mpascal-strings">, Group<m_Group>;
def mred_zone : Flag<"-mred-zone">, Group<m_Group>;
def mregparm_EQ : Joined<"-mregparm=">, Group<m_Group>;
@@ -994,6 +996,7 @@ def undef : Flag<"-undef">, Group<u_Group>, Flags<[CC1Option]>,
def unexported__symbols__list : Separate<"-unexported_symbols_list">;
def u : JoinedOrSeparate<"-u">, Group<u_Group>;
def use_gold_plugin : Flag<"-use-gold-plugin">;
+def use_collect2 : Flag<"-use-collect2">;
def v : Flag<"-v">, Flags<[CC1Option]>,
HelpText<"Show commands to run and use verbose output">;
def verify : Flag<"-verify">, Flags<[DriverOption,CC1Option]>,
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 240d66f..48ecd0b 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -1790,7 +1790,7 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
break;
case llvm::Triple::Linux:
if (Target.getArch() == llvm::Triple::hexagon)
- TC = new toolchains::Hexagon_TC(*this, Target);
+ TC = new toolchains::Hexagon_TC(*this, Target, Args);
else
TC = new toolchains::Linux(*this, Target, Args);
break;
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 8876d95..e03fad7 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -1422,11 +1422,112 @@ const char *Generic_GCC::GetForcedPicModel() const {
}
/// Hexagon Toolchain
-Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple)
- : ToolChain(D, Triple) {
- getProgramPaths().push_back(getDriver().getInstalledDir());
- if (getDriver().getInstalledDir() != getDriver().Dir.c_str())
- getProgramPaths().push_back(getDriver().Dir);
+std::string Hexagon_TC::GetGnuDir(const std::string &InstalledDir)
+{
+ std::string InstallRelDir;
+ std::string PrefixRelDir;
+
+ // Locate the rest of the toolchain ...
+ if (strlen(GCC_INSTALL_PREFIX))
+ return std::string(GCC_INSTALL_PREFIX);
+ else if (llvm::sys::fs::exists(InstallRelDir = InstalledDir + "/../../gnu"))
+ return InstallRelDir;
+ else if (llvm::sys::fs::exists(
+ PrefixRelDir = std::string(LLVM_PREFIX) + "/../gnu"))
+ return PrefixRelDir;
+ else
+ return InstallRelDir;
+}
+
+static void GetHexagonLibraryPaths(
+ const ArgList &Args,
+ const std::string Ver,
+ const std::string MarchString,
+ const std::string &InstalledDir,
+ ToolChain::path_list *LibPaths)
+{
+ bool buildingLib = Args.hasArg(options::OPT_shared);
+
+ //----------------------------------------------------------------------------
+ // -L Args
+ //----------------------------------------------------------------------------
+ for (arg_iterator
+ it = Args.filtered_begin(options::OPT_L),
+ ie = Args.filtered_end();
+ it != ie;
+ ++it) {
+ for (unsigned i = 0, e = (*it)->getNumValues(); i != e; ++i)
+ LibPaths->push_back((*it)->getValue(Args, i));
+ }
+
+ //----------------------------------------------------------------------------
+ // Other standard paths
+ //----------------------------------------------------------------------------
+ const std::string MarchSuffix = "/" + MarchString;
+ const std::string G0Suffix = "/G0";
+ const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
+ const std::string RootDir = Hexagon_TC::GetGnuDir(InstalledDir) + "/";
+
+ // lib/gcc/hexagon/...
+ std::string LibGCCHexagonDir = RootDir + "lib/gcc/hexagon/";
+ if (buildingLib) {
+ LibPaths->push_back(LibGCCHexagonDir + Ver + MarchG0Suffix);
+ LibPaths->push_back(LibGCCHexagonDir + Ver + G0Suffix);
+ }
+ LibPaths->push_back(LibGCCHexagonDir + Ver + MarchSuffix);
+ LibPaths->push_back(LibGCCHexagonDir + Ver);
+
+ // lib/gcc/...
+ LibPaths->push_back(RootDir + "lib/gcc");
+
+ // hexagon/lib/...
+ std::string HexagonLibDir = RootDir + "hexagon/lib";
+ if (buildingLib) {
+ LibPaths->push_back(HexagonLibDir + MarchG0Suffix);
+ LibPaths->push_back(HexagonLibDir + G0Suffix);
+ }
+ LibPaths->push_back(HexagonLibDir + MarchSuffix);
+ LibPaths->push_back(HexagonLibDir);
+}
+
+Hexagon_TC::Hexagon_TC(const Driver &D, const llvm::Triple& Triple,
+ const ArgList &Args)
+ : Linux(D, Triple, Args) {
+ const std::string InstalledDir(getDriver().getInstalledDir());
+
+ // Note: Generic_GCC::Generic_GCC adds InstalledDir and DriverDir
+
+ const std::string GnuDir = Hexagon_TC::GetGnuDir(InstalledDir);
+
+ const std::string BinDir(GnuDir + "/bin");
+ if (llvm::sys::fs::exists(BinDir))
+ getProgramPaths().push_back(BinDir);
+
+ // Determine version of GCC Libraries and Headers to use
+ const std::string HexagonDir(GnuDir + "/lib/gcc/hexagon");
+ llvm::error_code ec;
+ GCCVersion MaxVersion= GCCVersion::Parse("0.0.0");
+ for (llvm::sys::fs::directory_iterator di(HexagonDir, ec), de;
+ !ec && di != de; di = di.increment(ec)) {
+ GCCVersion cv = GCCVersion::Parse(llvm::sys::path::filename(di->path()));
+ if (MaxVersion < cv)
+ MaxVersion = cv;
+ }
+ GCCLibAndIncVersion= MaxVersion;
+
+ ToolChain::path_list *LibPaths= &getFilePaths();
+
+ // Remove paths added by Linux toolchain. Currently Hexagon_TC really targets
+ // 'elf' OS type, so the Linux paths are not appropriate. When we actually
+ // support 'linux' we'll need to fix this up
+ LibPaths->clear();
+
+ GetHexagonLibraryPaths(
+ Args,
+ GetGCCLibAndIncVersion(),
+ GetTargetCPU(Args),
+ InstalledDir,
+ LibPaths);
}
Hexagon_TC::~Hexagon_TC() {
@@ -1485,7 +1586,100 @@ const char *Hexagon_TC::GetDefaultRelocationModel() const {
const char *Hexagon_TC::GetForcedPicModel() const {
return 0;
-} // End Hexagon
+}
+
+void Hexagon_TC::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+ const Driver &D = getDriver();
+
+ if (DriverArgs.hasArg(options::OPT_nostdinc))
+ return;
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc))
+ return;
+
+ llvm::sys::Path InstallDir(D.InstalledDir);
+ std::string Ver(GetGCCLibAndIncVersion());
+ std::string GnuDir = Hexagon_TC::GetGnuDir(D.InstalledDir);
+ std::string HexagonDir(GnuDir +
+ "/lib/gcc/hexagon/" +
+ Ver);
+ addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include");
+ addExternCSystemInclude(DriverArgs, CC1Args, HexagonDir + "/include-fixed");
+ addExternCSystemInclude(DriverArgs, CC1Args,
+ GnuDir +
+ "/hexagon/include");
+}
+
+void Hexagon_TC::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const {
+
+ if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
+ DriverArgs.hasArg(options::OPT_nostdincxx))
+ return;
+
+ const Driver &D = getDriver();
+ llvm::sys::Path IncludeDir(Hexagon_TC::GetGnuDir(D.InstalledDir));
+
+ IncludeDir.appendComponent ("hexagon/include/c++/4.4.0/");
+ addSystemInclude (DriverArgs, CC1Args, IncludeDir.str());
+}
+
+ToolChain::CXXStdlibType
+Hexagon_TC::GetCXXStdlibType(const ArgList &Args) const {
+ Arg *A = Args.getLastArg(options::OPT_stdlib_EQ);
+ if (!A)
+ return ToolChain::CST_Libstdcxx;
+
+ StringRef Value = A->getValue(Args);
+ if (Value != "libstdc++") {
+ getDriver().Diag(diag::err_drv_invalid_stdlib_name)
+ << A->getAsString(Args);
+ }
+
+ return ToolChain::CST_Libstdcxx;
+}
+
+static Arg* GetLastHexagonArchArg (const ArgList &Args)
+{
+ Arg * A = NULL;
+
+ for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
+ it != ie; ++it) {
+ if ((*it)->getOption().matches(options::OPT_march_EQ) ||
+ (*it)->getOption().matches(options::OPT_mcpu_EQ)) {
+ A = *it;
+ A->claim();
+ }
+ else if ((*it)->getOption().matches(options::OPT_m_Joined)){
+ StringRef Value = (*it)->getValue(Args,0);
+ if (Value.startswith("v")) {
+ A = *it;
+ A->claim();
+ }
+ }
+ }
+ return A;
+}
+
+StringRef Hexagon_TC::GetTargetCPU(const ArgList &Args)
+{
+ Arg *A;
+ llvm::StringRef WhichHexagon;
+
+ // Select the default CPU (v4) if none was given or detection failed.
+ if ((A = GetLastHexagonArchArg (Args))) {
+ WhichHexagon = A->getValue(Args);
+ if (WhichHexagon == "")
+ return "v4";
+ else if (WhichHexagon.startswith("hexagon"))
+ return WhichHexagon.substr(sizeof("hexagon") - 1);
+ else
+ return WhichHexagon;
+ }
+ else
+ return "v4";
+}
+// End Hexagon
/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h
index 752cdfd..6110695 100644
--- a/lib/Driver/ToolChains.h
+++ b/lib/Driver/ToolChains.h
@@ -144,22 +144,6 @@ protected:
/// @}
};
-class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public ToolChain {
-protected:
- mutable llvm::DenseMap<unsigned, Tool*> Tools;
-
-public:
- Hexagon_TC(const Driver &D, const llvm::Triple& Triple);
- ~Hexagon_TC();
-
- virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
- const ActionList &Inputs) const;
-
- virtual bool IsUnwindTablesDefault() const;
- virtual const char *GetDefaultRelocationModel() const;
- virtual const char *GetForcedPicModel() const;
-};
-
/// Darwin - The base Darwin tool chain.
class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
public:
@@ -529,6 +513,35 @@ private:
ArgStringList &CC1Args);
};
+class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public Linux {
+protected:
+ mutable llvm::DenseMap<unsigned, Tool*> Tools;
+
+ GCCVersion GCCLibAndIncVersion;
+
+public:
+ Hexagon_TC(const Driver &D, const llvm::Triple& Triple,
+ const ArgList &Args);
+ ~Hexagon_TC();
+
+ virtual Tool &SelectTool(const Compilation &C, const JobAction &JA,
+ const ActionList &Inputs) const;
+
+ virtual bool IsUnwindTablesDefault() const;
+ virtual const char *GetDefaultRelocationModel() const;
+ virtual const char *GetForcedPicModel() const;
+ virtual void AddClangSystemIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const;
+ virtual void AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs,
+ ArgStringList &CC1Args) const;
+ virtual CXXStdlibType GetCXXStdlibType(const ArgList &Args) const;
+
+ StringRef GetGCCLibAndIncVersion() const { return GCCLibAndIncVersion.Text; }
+
+ static std::string GetGnuDir(const std::string &InstalledDir);
+
+ static StringRef GetTargetCPU(const ArgList &Args);
+};
/// TCEToolChain - A tool chain using the llvm bitcode tools to perform
/// all subcommands. See http://tce.cs.tut.fi for our peculiar target.
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index d4a5372..5cfcfaa 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1169,61 +1169,31 @@ void Clang::AddX86TargetArgs(const ArgList &Args,
}
}
-static Arg* getLastHexagonArchArg (const ArgList &Args)
-{
- Arg * A = NULL;
-
- for (ArgList::const_iterator it = Args.begin(), ie = Args.end();
- it != ie; ++it) {
- if ((*it)->getOption().matches(options::OPT_march_EQ) ||
- (*it)->getOption().matches(options::OPT_mcpu_EQ)) {
- A = *it;
- A->claim();
- }
- else if ((*it)->getOption().matches(options::OPT_m_Joined)){
- StringRef Value = (*it)->getValue(Args,0);
- if (Value.startswith("v")) {
- A = *it;
- A->claim();
- }
- }
- }
- return A;
-}
-
-static StringRef getHexagonTargetCPU(const ArgList &Args)
-{
- Arg *A;
- llvm::StringRef WhichHexagon;
-
- // Select the default CPU (v4) if none was given or detection failed.
- if ((A = getLastHexagonArchArg (Args))) {
- WhichHexagon = A->getValue(Args);
- if (WhichHexagon == "")
- return "v4";
- else
- return WhichHexagon;
- }
- else
- return "v4";
-}
-
void Clang::AddHexagonTargetArgs(const ArgList &Args,
ArgStringList &CmdArgs) const {
llvm::Triple Triple = getToolChain().getTriple();
CmdArgs.push_back("-target-cpu");
- CmdArgs.push_back(Args.MakeArgString("hexagon" + getHexagonTargetCPU(Args)));
+ CmdArgs.push_back(Args.MakeArgString(
+ "hexagon"
+ + toolchains::Hexagon_TC::GetTargetCPU(Args)));
CmdArgs.push_back("-fno-signed-char");
- CmdArgs.push_back("-nobuiltininc");
-
- if (Args.hasArg(options::OPT_mqdsp6_compat))
- CmdArgs.push_back("-mqdsp6-compat");
-
+ CmdArgs.push_back("-mqdsp6-compat");
+ CmdArgs.push_back("-Wreturn-type");
+ bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
+ Args.hasArg(options::OPT_fpic));
if (Arg *A = Args.getLastArg(options::OPT_G,
+ options::OPT_G_EQ,
+ options::OPT_fpic,
+ options::OPT_fPIC,
options::OPT_msmall_data_threshold_EQ)) {
- std::string SmallDataThreshold="-small-data-threshold=";
- SmallDataThreshold += A->getValue(Args);
+ // "-G0", "-G 0", and "-G=0" are the same driver flags.
+ // They are mapped to llvm flag "-hexagon-small-data-threshold=0".
+ std::string SmallDataThreshold="-hexagon-small-data-threshold=";
+ if(PICEnabled)
+ SmallDataThreshold += "0";
+ else
+ SmallDataThreshold += A->getValue(Args);
CmdArgs.push_back ("-mllvm");
CmdArgs.push_back(Args.MakeArgString(SmallDataThreshold));
A->claim();
@@ -3297,9 +3267,10 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
const Driver &D = getToolChain().getDriver();
ArgStringList CmdArgs;
-
+ bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
+ Args.hasArg(options::OPT_fpic));
std::string MarchString = "-march=";
- MarchString += getHexagonTargetCPU(Args);
+ MarchString += toolchains::Hexagon_TC::GetTargetCPU(Args);
CmdArgs.push_back(Args.MakeArgString(MarchString));
RenderExtraToolArgs(JA, CmdArgs);
@@ -3312,6 +3283,21 @@ void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-fsyntax-only");
}
+ if (Arg *A = Args.getLastArg(options::OPT_G,
+ options::OPT_G_EQ,
+ options::OPT_fpic,
+ options::OPT_fPIC,
+ options::OPT_msmall_data_threshold_EQ)) {
+ if(PICEnabled)
+ CmdArgs.push_back(Args.MakeArgString(std::string("-G0")));
+ else
+ CmdArgs.push_back(Args.MakeArgString(std::string("-G")
+ + A->getValue(Args)));
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_g_Group);
+ Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA,
+ options::OPT_Xassembler);
// Only pass -x if gcc will understand it; otherwise hope gcc
// understands the suffix correctly. The main use case this would go
@@ -3358,77 +3344,192 @@ void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA,
const ArgList &Args,
const char *LinkingOutput) const {
- const Driver &D = getToolChain().getDriver();
+ const toolchains::Hexagon_TC& ToolChain =
+ static_cast<const toolchains::Hexagon_TC&>(getToolChain());
+ const Driver &D = ToolChain.getDriver();
+
ArgStringList CmdArgs;
- for (ArgList::const_iterator
- it = Args.begin(), ie = Args.end(); it != ie; ++it) {
- Arg *A = *it;
- if (A->getOption().hasForwardToGCC()) {
- // Don't forward any -g arguments to assembly steps.
- if (isa<AssembleJobAction>(JA) &&
- A->getOption().matches(options::OPT_g_Group))
- continue;
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ bool hasStaticArg = Args.hasArg(options::OPT_static);
+ bool buildingLib = Args.hasArg(options::OPT_shared);
+ bool buildPIE = Args.hasArg(options::OPT_pie);
+ bool PICEnabled = (Args.hasArg(options::OPT_fPIC) ||
+ Args.hasArg(options::OPT_fpic));
+ bool incStdLib = !Args.hasArg(options::OPT_nostdlib);
+ bool incStartFiles = !Args.hasArg(options::OPT_nostartfiles);
+ bool incDefLibs = !Args.hasArg(options::OPT_nodefaultlibs);
+ bool useShared = buildingLib && !hasStaticArg;
+
+ //----------------------------------------------------------------------------
+ // Silence warnings for various options
+ //----------------------------------------------------------------------------
- // It is unfortunate that we have to claim here, as this means
- // we will basically never report anything interesting for
- // platforms using a generic gcc, even if we are just using gcc
- // to get to the assembler.
- A->claim();
- A->render(Args, CmdArgs);
- }
+ Args.ClaimAllArgs(options::OPT_g_Group);
+ Args.ClaimAllArgs(options::OPT_emit_llvm);
+ Args.ClaimAllArgs(options::OPT_w); // Other warning options are already
+ // handled somewhere else.
+ Args.ClaimAllArgs(options::OPT_static_libgcc);
+
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ if (Args.hasArg(options::OPT_s))
+ CmdArgs.push_back("-s");
+
+ for (std::vector<std::string>::const_iterator i = ToolChain.ExtraOpts.begin(),
+ e = ToolChain.ExtraOpts.end();
+ i != e; ++i)
+ CmdArgs.push_back(i->c_str());
+
+ std::string MarchString = toolchains::Hexagon_TC::GetTargetCPU(Args);
+ CmdArgs.push_back(Args.MakeArgString("-m" + MarchString));
+
+ if (buildingLib) {
+ CmdArgs.push_back("-shared");
+ CmdArgs.push_back("-call_shared"); // should be the default, but doing as
+ // hexagon-gcc does
}
- RenderExtraToolArgs(JA, CmdArgs);
+ if (hasStaticArg)
+ CmdArgs.push_back("-static");
- // Add Arch Information
- Arg *A;
- if ((A = getLastHexagonArchArg(Args))) {
- if (A->getOption().matches(options::OPT_m_Joined))
- A->render(Args, CmdArgs);
+ if (buildPIE && !buildingLib)
+ CmdArgs.push_back("-pie");
+
+ if (Arg *A = Args.getLastArg(options::OPT_G,
+ options::OPT_G_EQ,
+ options::OPT_fPIC,
+ options::OPT_fpic,
+ options::OPT_msmall_data_threshold_EQ)) {
+ if(PICEnabled)
+ CmdArgs.push_back(Args.MakeArgString(std::string("-G0")));
else
- CmdArgs.push_back (Args.MakeArgString("-m" + getHexagonTargetCPU(Args)));
+ CmdArgs.push_back(Args.MakeArgString(std::string("-G")
+ + A->getValue(Args)));
}
- else {
- CmdArgs.push_back (Args.MakeArgString("-m" + getHexagonTargetCPU(Args)));
+
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ CmdArgs.push_back("-o");
+ CmdArgs.push_back(Output.getFilename());
+
+ const std::string MarchSuffix = "/" + MarchString;
+ const std::string G0Suffix = "/G0";
+ const std::string MarchG0Suffix = MarchSuffix + G0Suffix;
+ const std::string RootDir = toolchains::Hexagon_TC::GetGnuDir(D.InstalledDir)
+ + "/";
+ const std::string StartFilesDir = RootDir
+ + "hexagon/lib"
+ + (buildingLib
+ ? MarchG0Suffix : MarchSuffix);
+
+ //----------------------------------------------------------------------------
+ // moslib
+ //----------------------------------------------------------------------------
+ std::vector<std::string> oslibs;
+ bool hasStandalone= false;
+
+ for (arg_iterator it = Args.filtered_begin(options::OPT_moslib_EQ),
+ ie = Args.filtered_end(); it != ie; ++it) {
+ (*it)->claim();
+ oslibs.push_back((*it)->getValue(Args));
+ hasStandalone = hasStandalone || (oslibs.back() == "standalone");
+ }
+ if (oslibs.empty()) {
+ oslibs.push_back("standalone");
+ hasStandalone = true;
}
- CmdArgs.push_back("-mqdsp6-compat");
+ //----------------------------------------------------------------------------
+ // Start Files
+ //----------------------------------------------------------------------------
+ if (incStdLib && incStartFiles) {
- const char *GCCName;
- if (C.getDriver().CCCIsCXX)
- GCCName = "hexagon-g++";
- else
- GCCName = "hexagon-gcc";
- const char *Exec =
- Args.MakeArgString(getToolChain().GetProgramPath(GCCName));
+ if (!buildingLib) {
+ if (hasStandalone) {
+ CmdArgs.push_back(
+ Args.MakeArgString(StartFilesDir + "/crt0_standalone.o"));
+ }
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/crt0.o"));
+ }
+ if (useShared)
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/initS.o"));
+ else
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/init.o"));
+ }
+
+ //----------------------------------------------------------------------------
+ // Library Search Paths
+ //----------------------------------------------------------------------------
+ const ToolChain::path_list &LibPaths = ToolChain.getFilePaths();
+ for (ToolChain::path_list::const_iterator
+ i = LibPaths.begin(),
+ e = LibPaths.end();
+ i != e;
+ ++i)
+ CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + *i));
- if (Output.isFilename()) {
- CmdArgs.push_back("-o");
- CmdArgs.push_back(Output.getFilename());
- }
+ //----------------------------------------------------------------------------
+ //
+ //----------------------------------------------------------------------------
+ Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
+ Args.AddAllArgs(CmdArgs, options::OPT_e);
+ Args.AddAllArgs(CmdArgs, options::OPT_s);
+ Args.AddAllArgs(CmdArgs, options::OPT_t);
+ Args.AddAllArgs(CmdArgs, options::OPT_u_Group);
- for (InputInfoList::const_iterator
- it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) {
- const InputInfo &II = *it;
+ AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs);
- // Don't try to pass LLVM or AST inputs to a generic gcc.
- if (II.getType() == types::TY_LLVM_IR || II.getType() == types::TY_LTO_IR ||
- II.getType() == types::TY_LLVM_BC || II.getType() == types::TY_LTO_BC)
- D.Diag(clang::diag::err_drv_no_linker_llvm_support)
- << getToolChain().getTripleString();
- else if (II.getType() == types::TY_AST)
- D.Diag(clang::diag::err_drv_no_ast_support)
- << getToolChain().getTripleString();
+ //----------------------------------------------------------------------------
+ // Libraries
+ //----------------------------------------------------------------------------
+ if (incStdLib && incDefLibs) {
+ if (D.CCCIsCXX) {
+ ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+ CmdArgs.push_back("-lm");
+ }
- if (II.isFilename())
- CmdArgs.push_back(II.getFilename());
+ CmdArgs.push_back("--start-group");
+
+ if (!buildingLib) {
+ for(std::vector<std::string>::iterator i = oslibs.begin(),
+ e = oslibs.end(); i != e; ++i)
+ CmdArgs.push_back(Args.MakeArgString("-l" + *i));
+ CmdArgs.push_back("-lc");
+ }
+ CmdArgs.push_back("-lgcc");
+
+ CmdArgs.push_back("--end-group");
+ }
+
+ //----------------------------------------------------------------------------
+ // End files
+ //----------------------------------------------------------------------------
+ if (incStdLib && incStartFiles) {
+ if (useShared)
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/finiS.o"));
else
- // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ?
- II.getInputArg().render(Args, CmdArgs);
+ CmdArgs.push_back(Args.MakeArgString(StartFilesDir + "/fini.o"));
}
- C.addCommand(new Command(JA, *this, Exec, CmdArgs));
+ std::string Linker;
+ std::string Ver(ToolChain.GetGCCLibAndIncVersion());
+
+ // allow users to override the linker with 'collect2' in case 'hexagon-ld'
+ // isn't sufficient.
+ if (Args.hasArg(options::OPT_use_collect2))
+ Linker= RootDir + "libexec/gcc/hexagon/" + Ver + "/collect2";
+ else
+ Linker= ToolChain.GetProgramPath("hexagon-ld");
+
+ C.addCommand(
+ new Command(
+ JA, *this,
+ Args.MakeArgString(Linker), CmdArgs));
}
// Hexagon tools end.
--
1.7.6.4
More information about the cfe-commits
mailing list