diff options
author | Tony Linthicum <tlinth@codeaurora.org> | 2011-12-12 21:14:55 +0000 |
---|---|---|
committer | Tony Linthicum <tlinth@codeaurora.org> | 2011-12-12 21:14:55 +0000 |
commit | 9631939f82c0eaa6fb3936a0ce58a41adfbc9011 (patch) | |
tree | edc3b38cac22072580f9ed50264e1efd0f89ec9e /lib/Driver | |
parent | 60f24e781484250d3602261477d16321db7a157b (diff) |
Hexagon backend support
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146413 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver')
-rw-r--r-- | lib/Driver/HostInfo.cpp | 5 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 67 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 18 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 256 | ||||
-rw-r--r-- | lib/Driver/Tools.h | 38 |
5 files changed, 379 insertions, 5 deletions
diff --git a/lib/Driver/HostInfo.cpp b/lib/Driver/HostInfo.cpp index 292678bf8a..0e7879278a 100644 --- a/lib/Driver/HostInfo.cpp +++ b/lib/Driver/HostInfo.cpp @@ -575,6 +575,11 @@ ToolChain *LinuxHostInfo::CreateToolChain(const ArgList &Args, ToolChain *&TC = ToolChains[ArchName]; + if (!TC && !Arch.compare ("hexagon")) { + llvm::Triple TCTriple (getTriple()); + TC = new toolchains::Hexagon_TC (*this, TCTriple); + } + if (!TC) { llvm::Triple TCTriple(getTriple()); TCTriple.setArchName(ArchName); diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index e5b884be33..9ddc0bb3be 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1406,6 +1406,73 @@ const char *Generic_GCC::GetDefaultRelocationModel() const { const char *Generic_GCC::GetForcedPicModel() const { return 0; } +/// Hexagon Toolchain + +Hexagon_TC::Hexagon_TC(const HostInfo &Host, const llvm::Triple& Triple) + : ToolChain(Host, Triple) { + getProgramPaths().push_back(getDriver().getInstalledDir()); + if (getDriver().getInstalledDir() != getDriver().Dir.c_str()) + getProgramPaths().push_back(getDriver().Dir); +} + +Hexagon_TC::~Hexagon_TC() { + // Free tool implementations. + for (llvm::DenseMap<unsigned, Tool*>::iterator + it = Tools.begin(), ie = Tools.end(); it != ie; ++it) + delete it->second; +} + +Tool &Hexagon_TC::SelectTool(const Compilation &C, + const JobAction &JA, + const ActionList &Inputs) const { + Action::ActionClass Key; + // if (JA.getKind () == Action::CompileJobClass) + // Key = JA.getKind (); + // else + + if (getDriver().ShouldUseClangCompiler(C, JA, getTriple())) + Key = Action::AnalyzeJobClass; + else + Key = JA.getKind(); + // if ((JA.getKind () == Action::CompileJobClass) + // && (JA.getType () != types::TY_LTO_BC)) { + // Key = JA.getKind (); + // } + + Tool *&T = Tools[Key]; + if (!T) { + switch (Key) { + case Action::InputClass: + case Action::BindArchClass: + assert(0 && "Invalid tool kind."); + case Action::AnalyzeJobClass: + T = new tools::Clang(*this); break; + case Action::AssembleJobClass: + T = new tools::hexagon::Assemble(*this); break; + case Action::LinkJobClass: + T = new tools::hexagon::Link(*this); break; + default: + assert(false && "Unsupported action for Hexagon target."); + } + } + + return *T; +} + +bool Hexagon_TC::IsUnwindTablesDefault() const { + // FIXME: Gross; we should probably have some separate target + // definition, possibly even reusing the one in clang. + return getArchName() == "x86_64"; +} + +const char *Hexagon_TC::GetDefaultRelocationModel() const { + return "static"; +} + +const char *Hexagon_TC::GetForcedPicModel() const { + return 0; +} // End Hexagon + /// 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/ToolChains.h b/lib/Driver/ToolChains.h index aaf9ef143f..45bf0d88c2 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -136,7 +136,23 @@ protected: /// @} }; -/// Darwin - The base Darwin tool chain. +class LLVM_LIBRARY_VISIBILITY Hexagon_TC : public ToolChain { +protected: + mutable llvm::DenseMap<unsigned, Tool*> Tools; + +public: + Hexagon_TC(const HostInfo &Host, 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: /// The host version. diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index f410848cc7..46ec09c2f2 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -944,6 +944,81 @@ 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_mv2) || + (*it)->getOption().matches(options::OPT_mv3) || + (*it)->getOption().matches(options::OPT_mv4) || + (*it)->getOption().matches(options::OPT_march_EQ) || + (*it)->getOption().matches(options::OPT_mcpu_EQ)) { + A = *it; + A->claim(); + } + } + return A; +} + +static const char *getHexagonTargetCPU(const ArgList &Args) +{ + Arg *A; + llvm::StringRef WhichHexagon; + + if ((A = getLastHexagonArchArg (Args))) { + if ((A->getOption().matches(options::OPT_march_EQ)) || + (A->getOption().matches(options::OPT_mcpu_EQ))) { + WhichHexagon = A->getValue(Args); + if (WhichHexagon == "v2") + return "hexagonv2"; + else if (WhichHexagon == "v3") + return "hexagonv3"; + else if (WhichHexagon == "v4") + return "hexagonv4"; + else + assert (0 && "Unknown -march or -mcpu value"); + } + else { + if (A->getOption().matches(options::OPT_mv2)) + return "hexagonv2"; + else if (A->getOption().matches(options::OPT_mv3)) + return "hexagonv3"; + else if (A->getOption().matches(options::OPT_mv4)) + return "hexagonv4"; + else + assert(0 && "Unknown -m argument."); + } + } + else + return "hexagonv2"; +} + +void Clang::AddHexagonTargetArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { + llvm::Triple Triple = getToolChain().getTriple(); + + CmdArgs.push_back("-target-cpu"); + CmdArgs.push_back(getHexagonTargetCPU(Args)); + CmdArgs.push_back("-fno-signed-char"); + CmdArgs.push_back("-nobuiltininc"); + + if (Args.hasArg(options::OPT_mqdsp6_compat)) + CmdArgs.push_back("-mqdsp6-compat"); + + if (Arg *A = Args.getLastArg(options::OPT_G, + options::OPT_msmall_data_threshold_EQ)) { + std::string SmallDataThreshold="-small-data-threshold="; + SmallDataThreshold += A->getValue(Args); + CmdArgs.push_back ("-mllvm"); + CmdArgs.push_back(Args.MakeArgString(SmallDataThreshold)); + A->claim(); + } + + CmdArgs.push_back ("-mllvm"); + CmdArgs.push_back ("-machine-sink-split=0"); +} + static bool shouldUseExceptionTablesForObjCExceptions(unsigned objcABIVersion, const llvm::Triple &Triple) { @@ -1438,8 +1513,14 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, case llvm::Triple::x86_64: AddX86TargetArgs(Args, CmdArgs); break; + + case llvm::Triple::hexagon: + AddHexagonTargetArgs(Args, CmdArgs); + break; } + + // Pass the linker version in use. if (Arg *A = Args.getLastArg(options::OPT_mlinker_version_EQ)) { CmdArgs.push_back("-target-linker-version"); @@ -1872,10 +1953,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, !Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti)) CmdArgs.push_back("-fno-rtti"); - // -fshort-enums=0 is default. - // FIXME: Are there targers where -fshort-enums is on by default ? + // -fshort-enums=0 is default for all architectures except Hexagon. if (Args.hasFlag(options::OPT_fshort_enums, - options::OPT_fno_short_enums, false)) + options::OPT_fno_short_enums, + getToolChain().getTriple().getArch() == + llvm::Triple::hexagon)) CmdArgs.push_back("-fshort-enums"); // -fsigned-char is default. @@ -1892,7 +1974,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (KernelOrKext || !Args.hasFlag(options::OPT_fuse_cxa_atexit, options::OPT_fno_use_cxa_atexit, getToolChain().getTriple().getOS() != llvm::Triple::Cygwin && - getToolChain().getTriple().getOS() != llvm::Triple::MinGW32)) + getToolChain().getTriple().getOS() != llvm::Triple::MinGW32 && + getToolChain().getTriple().getArch() != + llvm::Triple::hexagon)) CmdArgs.push_back("-fno-use-cxa-atexit"); // -fms-extensions=0 is default. @@ -2475,6 +2559,8 @@ void gcc::Common::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-fsyntax-only"); } + 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 @@ -2574,6 +2660,168 @@ void gcc::Link::RenderExtraToolArgs(const JobAction &JA, // The types are (hopefully) good enough. } +// Hexagon tools start. +void hexagon::Assemble::RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const { + +} +void hexagon::Assemble::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + + const Driver &D = getToolChain().getDriver(); + ArgStringList CmdArgs; + + std::string MarchString = "-march="; + MarchString += getHexagonTargetCPU(Args); + CmdArgs.push_back(Args.MakeArgString(MarchString)); + + RenderExtraToolArgs(JA, CmdArgs); + + if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } else { + assert(Output.isNothing() && "Unexpected output"); + CmdArgs.push_back("-fsyntax-only"); + } + + + // Only pass -x if gcc will understand it; otherwise hope gcc + // understands the suffix correctly. The main use case this would go + // wrong in is for linker inputs if they happened to have an odd + // suffix; really the only way to get this to happen is a command + // like '-x foobar a.c' which will treat a.c like a linker input. + // + // FIXME: For the linker case specifically, can we safely convert + // inputs into '-Wl,' options? + for (InputInfoList::const_iterator + it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { + const InputInfo &II = *it; + + // 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(); + + if (II.isFilename()) + CmdArgs.push_back(II.getFilename()); + else + // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ? + II.getInputArg().render(Args, CmdArgs); + } + + const char *GCCName = "hexagon-as"; + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + +} +void hexagon::Link::RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const { + // The types are (hopefully) good enough. +} + +void hexagon::Link::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + + const Driver &D = getToolChain().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; + + // 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); + } + } + + RenderExtraToolArgs(JA, CmdArgs); + + // Add Arch Information + Arg *A; + if ((A = getLastHexagonArchArg (Args))) { + if ((A->getOption().matches(options::OPT_march_EQ)) || + (A->getOption().matches(options::OPT_mcpu_EQ))) { + llvm::StringRef WhichHexagon = A->getValue(Args); + if (WhichHexagon == "v2") + CmdArgs.push_back("-mv2"); + else if (WhichHexagon == "v3") + CmdArgs.push_back ("-mv3"); + else if (WhichHexagon == "v4") + CmdArgs.push_back ("-mv4"); + else + assert (0 && "Unknown -march or -mcpu value"); + } + else { + if (A->getOption().matches(options::OPT_mv2) || + A->getOption().matches(options::OPT_mv3) || + A->getOption().matches(options::OPT_mv4)) + A->render(Args, CmdArgs); + else + assert(0 && "Unknown -m argument."); + } + + } + CmdArgs.push_back("-mqdsp6-compat"); + + const char *GCCName; + if (C.getDriver().CCCIsCXX) + GCCName = "hexagon-g++"; + else + GCCName = "hexagon-gcc"; + const char *Exec = + Args.MakeArgString(getToolChain().GetProgramPath(GCCName)); + + if (Output.isFilename()) { + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + } + + for (InputInfoList::const_iterator + it = Inputs.begin(), ie = Inputs.end(); it != ie; ++it) { + const InputInfo &II = *it; + + // 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(); + + if (II.isFilename()) + CmdArgs.push_back(II.getFilename()); + else + // Don't render as input, we need gcc to do the translations. FIXME: Pranav: What is this ? + II.getInputArg().render(Args, CmdArgs); + } + C.addCommand(new Command(JA, *this, Exec, CmdArgs)); + +} +// Hexagon tools end. + + const char *darwin::CC1::getCC1Name(types::ID Type) const { switch (Type) { default: diff --git a/lib/Driver/Tools.h b/lib/Driver/Tools.h index d81c987cf0..c06e22b1d5 100644 --- a/lib/Driver/Tools.h +++ b/lib/Driver/Tools.h @@ -41,6 +41,7 @@ namespace tools { void AddMIPSTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; void AddSparcTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; void AddX86TargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const; + void AddHexagonTargetArgs (const ArgList &Args, ArgStringList &CmdArgs) const; public: Clang(const ToolChain &TC) : Tool("clang", "clang frontend", TC) {} @@ -152,6 +153,43 @@ namespace gcc { }; } // end namespace gcc +namespace hexagon { + // For Hexagon, we do not need to instantiate tools for PreProcess, PreCompile and Compile. + // We simply use "clang -cc1" for those actions. + class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { + public: + Assemble(const ToolChain &TC) : Tool("hexagon::Assemble", + "hexagon-as", TC) {} + + virtual bool hasIntegratedCPP() const { return false; } + + virtual void RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const; + virtual void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &TCArgs, + const char *LinkingOutput) const; + }; + + class LLVM_LIBRARY_VISIBILITY Link : public Tool { + public: + Link(const ToolChain &TC) : Tool("hexagon::Link", + "hexagon-ld", TC) {} + + virtual bool hasIntegratedCPP() const { return false; } + + virtual void RenderExtraToolArgs(const JobAction &JA, + ArgStringList &CmdArgs) const; + virtual void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &TCArgs, + const char *LinkingOutput) const; + }; +} // end namespace hexagon. + + namespace darwin { class LLVM_LIBRARY_VISIBILITY DarwinTool : public Tool { protected: |