Index: cfe/trunk/lib/Driver/Driver.cpp =================================================================== --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/lib/Driver/Driver.cpp @@ -2106,6 +2106,8 @@ TC = new toolchains::Hexagon_TC(*this, Target, Args); else if (Target.getArch() == llvm::Triple::xcore) TC = new toolchains::XCore(*this, Target, Args); + else if (Target.getArch() == llvm::Triple::shave) + TC = new toolchains::SHAVEToolChain(*this, Target, Args); else if (Target.isOSBinFormatELF()) TC = new toolchains::Generic_ELF(*this, Target, Args); else if (Target.isOSBinFormatMachO()) Index: cfe/trunk/lib/Driver/ToolChains.h =================================================================== --- cfe/trunk/lib/Driver/ToolChains.h +++ cfe/trunk/lib/Driver/ToolChains.h @@ -861,6 +861,27 @@ llvm::opt::ArgStringList &CmdArgs) const override; }; +/// SHAVEToolChain - A tool chain using the compiler installed by the the +// Movidius SDK into MV_TOOLS_DIR (which we assume will be copied to llvm's +// installation dir) to perform all subcommands. +class LLVM_LIBRARY_VISIBILITY SHAVEToolChain : public Generic_GCC { +public: + SHAVEToolChain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + ~SHAVEToolChain() override; + + virtual Tool *SelectTool(const JobAction &JA) const override; + +protected: + Tool *getTool(Action::ActionClass AC) const override; + Tool *buildAssembler() const override; + Tool *buildLinker() const override; + +private: + mutable std::unique_ptr Compiler; + mutable std::unique_ptr Assembler; +}; + } // end namespace toolchains } // end namespace driver } // end namespace clang Index: cfe/trunk/lib/Driver/ToolChains.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains.cpp +++ cfe/trunk/lib/Driver/ToolChains.cpp @@ -3727,3 +3727,46 @@ ArgStringList &CmdArgs) const { // We don't output any lib args. This is handled by xcc. } + +// SHAVEToolChain does not call Clang's C compiler. +// We override SelectTool to avoid testing ShouldUseClangCompiler(). +Tool *SHAVEToolChain::SelectTool(const JobAction &JA) const { + switch (JA.getKind()) { + case Action::CompileJobClass: + if (!Compiler) + Compiler.reset(new tools::SHAVE::Compile(*this)); + return Compiler.get(); + case Action::AssembleJobClass: + if (!Assembler) + Assembler.reset(new tools::SHAVE::Assemble(*this)); + return Assembler.get(); + default: + return ToolChain::getTool(JA.getKind()); + } +} + +SHAVEToolChain::SHAVEToolChain(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_GCC(D, Triple, Args) {} + +SHAVEToolChain::~SHAVEToolChain() {} + +/// Following are methods necessary to avoid having moviClang be an abstract +/// class. + +Tool *SHAVEToolChain::getTool(Action::ActionClass AC) const { + // SelectTool() must find a tool using the method in the superclass. + // There's nothing we can do if that fails. + llvm_unreachable("SHAVEToolChain can't getTool"); +} + +Tool *SHAVEToolChain::buildLinker() const { + // SHAVEToolChain executables can not be linked except by the vendor tools. + llvm_unreachable("SHAVEToolChain can't buildLinker"); +} + +Tool *SHAVEToolChain::buildAssembler() const { + // This one you'd think should be reachable since we expose an + // assembler to the driver, except not the way it expects. + llvm_unreachable("SHAVEToolChain can't buildAssembler"); +} Index: cfe/trunk/lib/Driver/Tools.h =================================================================== --- cfe/trunk/lib/Driver/Tools.h +++ cfe/trunk/lib/Driver/Tools.h @@ -733,6 +733,33 @@ }; } +/// SHAVE tools -- Directly call moviCompile and moviAsm +namespace SHAVE { +class LLVM_LIBRARY_VISIBILITY Compile : public Tool { +public: + Compile(const ToolChain &TC) : Tool("moviCompile", "movicompile", TC) {} + + bool hasIntegratedCPP() const override { return true; } + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; + +class LLVM_LIBRARY_VISIBILITY Assemble : public Tool { +public: + Assemble(const ToolChain &TC) : Tool("moviAsm", "moviAsm", TC) {} + + bool hasIntegratedCPP() const override { return false; } // not sure. + + void ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, const InputInfoList &Inputs, + const llvm::opt::ArgList &TCArgs, + const char *LinkingOutput) const override; +}; +} // end namespace SHAVE + } // end namespace tools } // end namespace driver } // end namespace clang Index: cfe/trunk/lib/Driver/Tools.cpp =================================================================== --- cfe/trunk/lib/Driver/Tools.cpp +++ cfe/trunk/lib/Driver/Tools.cpp @@ -9098,3 +9098,81 @@ C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs)); } + +void tools::SHAVE::Compile::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + + ArgStringList CmdArgs; + + assert(Inputs.size() == 1); + const InputInfo &II = Inputs[0]; + assert(II.getType() == types::TY_C || II.getType() == types::TY_CXX); + assert(Output.getType() == types::TY_PP_Asm); // Require preprocessed asm. + + // Append all -I, -iquote, -isystem paths. + Args.AddAllArgs(CmdArgs, options::OPT_clang_i_Group); + // These are spelled the same way in clang and moviCompile. + Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U); + + CmdArgs.push_back("-DMYRIAD2"); + CmdArgs.push_back("-mcpu=myriad2"); + CmdArgs.push_back("-S"); + + // Any -O option passes through without translation. What about -Ofast ? + if (Arg *A = Args.getLastArg(options::OPT_O_Group)) + A->render(Args, CmdArgs); + + if (Args.hasFlag(options::OPT_ffunction_sections, + options::OPT_fno_function_sections)) { + CmdArgs.push_back("-ffunction-sections"); + } + if (Args.hasArg(options::OPT_fno_inline_functions)) + CmdArgs.push_back("-fno-inline-functions"); + + CmdArgs.push_back("-fno-exceptions"); // Always do this even if unspecified. + + CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + + std::string Exec = + Args.MakeArgString(getToolChain().GetProgramPath("moviCompile")); + C.addCommand( + llvm::make_unique(JA, *this, Args.MakeArgString(Exec), CmdArgs)); +} + +void tools::SHAVE::Assemble::ConstructJob(Compilation &C, + const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + ArgStringList CmdArgs; + + assert(Inputs.size() == 1); + const InputInfo &II = Inputs[0]; + assert(II.getType() == types::TY_PP_Asm); // Require preprocessed asm input. + assert(Output.getType() == types::TY_Object); + + CmdArgs.push_back("-no6thSlotCompression"); + CmdArgs.push_back("-cv:myriad2"); // Chip Version ? + CmdArgs.push_back("-noSPrefixing"); + CmdArgs.push_back("-a"); // Mystery option. + for (auto Arg : Args.filtered(options::OPT_I)) { + Arg->claim(); + CmdArgs.push_back( + Args.MakeArgString(std::string("-i:") + Arg->getValue(0))); + } + CmdArgs.push_back("-elf"); // Output format. + CmdArgs.push_back(II.getFilename()); + CmdArgs.push_back( + Args.MakeArgString(std::string("-o:") + Output.getFilename())); + + std::string Exec = + Args.MakeArgString(getToolChain().GetProgramPath("moviAsm")); + C.addCommand( + llvm::make_unique(JA, *this, Args.MakeArgString(Exec), CmdArgs)); +} Index: cfe/trunk/test/Driver/shave-toolchain.c =================================================================== --- cfe/trunk/test/Driver/shave-toolchain.c +++ cfe/trunk/test/Driver/shave-toolchain.c @@ -0,0 +1,22 @@ +// Ensure that '-target shave' picks a different compiler. +// Also check that '-I' is turned into '-i:' for the assembler. + +// Note that since we don't know where movi tools are installed, +// the driver may or may not find a full path to them. +// That is, the 0th argument will be "/path/to/my/moviCompile" +// or just "moviCompile" depending on whether moviCompile is found. +// As such, we test only for a trailing quote in its rendering. +// The same goes for "moviAsm". + +// RUN: %clang -target shave -c -### %s -Icommon 2>&1 \ +// RUN: | FileCheck %s -check-prefix=movicompile +// movicompile: moviCompile" "-DMYRIAD2" +// movicompile: moviAsm" "-no6thSlotCompression" "-cv:myriad2" "-noSPrefixing" "-a" "-i:common" "-elf" + +// RUN: %clang -target shave -c -### %s -DEFINE_ME -UNDEFINE_ME 2>&1 \ +// RUN: | FileCheck %s -check-prefix=defines +// defines: "-D" "EFINE_ME" "-U" "NDEFINE_ME" + +// RUN: %clang -target shave -c -### %s -Icommon -iquote quotepath -isystem syspath 2>&1 \ +// RUN: | FileCheck %s -check-prefix=includes +// includes: "-iquote" "quotepath" "-isystem" "syspath"