1*0b57cec5SDimitry Andric //===--- RISCVToolchain.cpp - RISCV ToolChain Implementations ---*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "RISCVToolchain.h" 10*0b57cec5SDimitry Andric #include "CommonArgs.h" 11*0b57cec5SDimitry Andric #include "InputInfo.h" 12*0b57cec5SDimitry Andric #include "clang/Driver/Compilation.h" 13*0b57cec5SDimitry Andric #include "clang/Driver/Options.h" 14*0b57cec5SDimitry Andric #include "llvm/Option/ArgList.h" 15*0b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 16*0b57cec5SDimitry Andric #include "llvm/Support/Path.h" 17*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 18*0b57cec5SDimitry Andric 19*0b57cec5SDimitry Andric using namespace clang::driver; 20*0b57cec5SDimitry Andric using namespace clang::driver::toolchains; 21*0b57cec5SDimitry Andric using namespace clang::driver::tools; 22*0b57cec5SDimitry Andric using namespace clang; 23*0b57cec5SDimitry Andric using namespace llvm::opt; 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric /// RISCV Toolchain 26*0b57cec5SDimitry Andric RISCVToolChain::RISCVToolChain(const Driver &D, const llvm::Triple &Triple, 27*0b57cec5SDimitry Andric const ArgList &Args) 28*0b57cec5SDimitry Andric : Generic_ELF(D, Triple, Args) { 29*0b57cec5SDimitry Andric GCCInstallation.init(Triple, Args); 30*0b57cec5SDimitry Andric getFilePaths().push_back(computeSysRoot() + "/lib"); 31*0b57cec5SDimitry Andric if (GCCInstallation.isValid()) { 32*0b57cec5SDimitry Andric getFilePaths().push_back(GCCInstallation.getInstallPath().str()); 33*0b57cec5SDimitry Andric getProgramPaths().push_back( 34*0b57cec5SDimitry Andric (GCCInstallation.getParentLibPath() + "/../bin").str()); 35*0b57cec5SDimitry Andric } 36*0b57cec5SDimitry Andric } 37*0b57cec5SDimitry Andric 38*0b57cec5SDimitry Andric Tool *RISCVToolChain::buildLinker() const { 39*0b57cec5SDimitry Andric return new tools::RISCV::Linker(*this); 40*0b57cec5SDimitry Andric } 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric void RISCVToolChain::addClangTargetOptions( 43*0b57cec5SDimitry Andric const llvm::opt::ArgList &DriverArgs, 44*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args, 45*0b57cec5SDimitry Andric Action::OffloadKind) const { 46*0b57cec5SDimitry Andric CC1Args.push_back("-nostdsysteminc"); 47*0b57cec5SDimitry Andric CC1Args.push_back("-fuse-init-array"); 48*0b57cec5SDimitry Andric } 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric void RISCVToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 51*0b57cec5SDimitry Andric ArgStringList &CC1Args) const { 52*0b57cec5SDimitry Andric if (DriverArgs.hasArg(options::OPT_nostdinc)) 53*0b57cec5SDimitry Andric return; 54*0b57cec5SDimitry Andric 55*0b57cec5SDimitry Andric if (!DriverArgs.hasArg(options::OPT_nostdlibinc)) { 56*0b57cec5SDimitry Andric SmallString<128> Dir(computeSysRoot()); 57*0b57cec5SDimitry Andric llvm::sys::path::append(Dir, "include"); 58*0b57cec5SDimitry Andric addSystemInclude(DriverArgs, CC1Args, Dir.str()); 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric } 61*0b57cec5SDimitry Andric 62*0b57cec5SDimitry Andric void RISCVToolChain::addLibStdCxxIncludePaths( 63*0b57cec5SDimitry Andric const llvm::opt::ArgList &DriverArgs, 64*0b57cec5SDimitry Andric llvm::opt::ArgStringList &CC1Args) const { 65*0b57cec5SDimitry Andric const GCCVersion &Version = GCCInstallation.getVersion(); 66*0b57cec5SDimitry Andric StringRef TripleStr = GCCInstallation.getTriple().str(); 67*0b57cec5SDimitry Andric const Multilib &Multilib = GCCInstallation.getMultilib(); 68*0b57cec5SDimitry Andric addLibStdCXXIncludePaths(computeSysRoot() + "/include/c++/" + Version.Text, 69*0b57cec5SDimitry Andric "", TripleStr, "", "", Multilib.includeSuffix(), DriverArgs, CC1Args); 70*0b57cec5SDimitry Andric } 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric std::string RISCVToolChain::computeSysRoot() const { 73*0b57cec5SDimitry Andric if (!getDriver().SysRoot.empty()) 74*0b57cec5SDimitry Andric return getDriver().SysRoot; 75*0b57cec5SDimitry Andric 76*0b57cec5SDimitry Andric if (!GCCInstallation.isValid()) 77*0b57cec5SDimitry Andric return std::string(); 78*0b57cec5SDimitry Andric 79*0b57cec5SDimitry Andric StringRef LibDir = GCCInstallation.getParentLibPath(); 80*0b57cec5SDimitry Andric StringRef TripleStr = GCCInstallation.getTriple().str(); 81*0b57cec5SDimitry Andric std::string SysRootDir = LibDir.str() + "/../" + TripleStr.str(); 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric if (!llvm::sys::fs::exists(SysRootDir)) 84*0b57cec5SDimitry Andric return std::string(); 85*0b57cec5SDimitry Andric 86*0b57cec5SDimitry Andric return SysRootDir; 87*0b57cec5SDimitry Andric } 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric void RISCV::Linker::ConstructJob(Compilation &C, const JobAction &JA, 90*0b57cec5SDimitry Andric const InputInfo &Output, 91*0b57cec5SDimitry Andric const InputInfoList &Inputs, 92*0b57cec5SDimitry Andric const ArgList &Args, 93*0b57cec5SDimitry Andric const char *LinkingOutput) const { 94*0b57cec5SDimitry Andric const ToolChain &ToolChain = getToolChain(); 95*0b57cec5SDimitry Andric const Driver &D = ToolChain.getDriver(); 96*0b57cec5SDimitry Andric ArgStringList CmdArgs; 97*0b57cec5SDimitry Andric 98*0b57cec5SDimitry Andric if (!D.SysRoot.empty()) 99*0b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric std::string Linker = getToolChain().GetProgramPath(getShortName()); 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric bool WantCRTs = 104*0b57cec5SDimitry Andric !Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles); 105*0b57cec5SDimitry Andric 106*0b57cec5SDimitry Andric if (WantCRTs) { 107*0b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); 108*0b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); 109*0b57cec5SDimitry Andric } 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, options::OPT_L); 112*0b57cec5SDimitry Andric ToolChain.AddFilePathLibArgs(Args, CmdArgs); 113*0b57cec5SDimitry Andric Args.AddAllArgs(CmdArgs, 114*0b57cec5SDimitry Andric {options::OPT_T_Group, options::OPT_e, options::OPT_s, 115*0b57cec5SDimitry Andric options::OPT_t, options::OPT_Z_Flag, options::OPT_r}); 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric // TODO: add C++ includes and libs if compiling C++. 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric if (!Args.hasArg(options::OPT_nostdlib) && 122*0b57cec5SDimitry Andric !Args.hasArg(options::OPT_nodefaultlibs)) { 123*0b57cec5SDimitry Andric if (ToolChain.ShouldLinkCXXStdlib(Args)) 124*0b57cec5SDimitry Andric ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); 125*0b57cec5SDimitry Andric CmdArgs.push_back("--start-group"); 126*0b57cec5SDimitry Andric CmdArgs.push_back("-lc"); 127*0b57cec5SDimitry Andric CmdArgs.push_back("-lgloss"); 128*0b57cec5SDimitry Andric CmdArgs.push_back("--end-group"); 129*0b57cec5SDimitry Andric CmdArgs.push_back("-lgcc"); 130*0b57cec5SDimitry Andric } 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric if (WantCRTs) 133*0b57cec5SDimitry Andric CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric CmdArgs.push_back("-o"); 136*0b57cec5SDimitry Andric CmdArgs.push_back(Output.getFilename()); 137*0b57cec5SDimitry Andric C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker), 138*0b57cec5SDimitry Andric CmdArgs, Inputs)); 139*0b57cec5SDimitry Andric } 140*0b57cec5SDimitry Andric // RISCV tools end. 141