Index: lib/Driver/Driver.cpp =================================================================== --- lib/Driver/Driver.cpp +++ lib/Driver/Driver.cpp @@ -1569,8 +1569,9 @@ if (Input.getOption().matches(options::OPT_INPUT)) { const char *Name = Input.getValue(); Result = InputInfo(Name, A->getType(), Name); - } else + } else { Result = InputInfo(&Input, A->getType(), ""); + } return; } @@ -2105,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::MoviClang(*this, Target, Args); else if (Target.isOSBinFormatELF()) TC = new toolchains::Generic_ELF(*this, Target, Args); else if (Target.isOSBinFormatMachO()) Index: lib/Driver/ToolChains.h =================================================================== --- lib/Driver/ToolChains.h +++ lib/Driver/ToolChains.h @@ -872,6 +872,30 @@ llvm::opt::ArgStringList &CmdArgs) const override; }; +/// MoviClang - A tool chain using the compiler that the SDK installs +/// into MV_TOOLS_DIR (copied to llvm's installdir) to perform all subcommands. +class LLVM_LIBRARY_VISIBILITY MoviClang : public Generic_GCC { +public: + MoviClang(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + ~MoviClang() override; + + void printVerboseInfo(raw_ostream &OS) const override; + bool isPICDefault() const override; + bool isPIEDefault() const override; + bool isPICDefaultForced() const 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 moviCompile; + mutable std::unique_ptr moviAsm; +}; + } // end namespace toolchains } // end namespace driver } // end namespace clang Index: lib/Driver/ToolChains.cpp =================================================================== --- lib/Driver/ToolChains.cpp +++ lib/Driver/ToolChains.cpp @@ -3744,3 +3744,53 @@ ArgStringList &CmdArgs) const { // We don't output any lib args. This is handled by xcc. } + +bool MoviClang::isPICDefault() const { return true; } +bool MoviClang::isPIEDefault() const { return false; } +bool MoviClang::isPICDefaultForced() const { return false; } + +// MoviClang does not call Clang's C compiler. +// We override SelectTool to avoid testing ShouldUseClangCompiler(). +Tool *MoviClang::SelectTool(const JobAction &JA) const { + switch (JA.getKind()) { + case Action::CompileJobClass: + if (!moviCompile) + moviCompile.reset(new tools::movitool::Compile(*this)); + return moviCompile.get(); + case Action::AssembleJobClass: + if (!moviAsm) + moviAsm.reset(new tools::movitool::Assemble(*this)); + return moviAsm.get(); + default: + return ToolChain::getTool(JA.getKind()); + } +} + +MoviClang::MoviClang(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_GCC(D, Triple, Args) {} + +MoviClang::~MoviClang() {} + +/// Following are methods necessary to avoid having moviClang be an abstract +/// class. + +Tool *MoviClang::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("MoviClang can't getTool"); +} + +Tool *MoviClang::buildLinker() const { + // SHAVE executables can not be linked except by the vendor tools. + llvm_unreachable("MoviClang can't buildLinker"); +} + +Tool *MoviClang::buildAssembler() const { + // This one you'd think should be reachable since we expose an + // assembler to the driver, except not the way it expects. + // Maybe I'm "holding it wrong" ? + llvm_unreachable("MoviClang can't buildAssembler"); +} + +void MoviClang::printVerboseInfo(raw_ostream &OS) const {} Index: lib/Driver/Tools.h =================================================================== --- lib/Driver/Tools.h +++ lib/Driver/Tools.h @@ -731,6 +731,33 @@ }; } +/// movitool -- Directly call moviCompile and moviAsm +namespace movitool { +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 movitool + } // end namespace tools } // end namespace driver } // end namespace clang Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -9087,3 +9087,82 @@ C.addCommand(llvm::make_unique(JA, *this, Exec, CmdArgs)); } + +void tools::movitool::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::movitool::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: test/Driver/movi-shave.c =================================================================== --- /dev/null +++ test/Driver/movi-shave.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"