MSP430.cpp revision 343173
124269Speter//===--- MSP430.cpp - MSP430 Helpers for Tools ------------------*- C++ -*-===// 224269Speter// 324269Speter// The LLVM Compiler Infrastructure 424269Speter// 528345Sdyson// This file is distributed under the University of Illinois Open Source 628345Sdyson// License. See LICENSE.TXT for details. 728345Sdyson// 824269Speter//===----------------------------------------------------------------------===// 924269Speter 1024269Speter#include "MSP430.h" 1124269Speter#include "CommonArgs.h" 1224269Speter#include "Gnu.h" 1324269Speter#include "InputInfo.h" 1424269Speter#include "clang/Driver/Compilation.h" 1524269Speter#include "clang/Driver/Multilib.h" 1624269Speter#include "clang/Driver/Options.h" 1724269Speter#include "llvm/Option/ArgList.h" 1824269Speter#include "llvm/Support/FileSystem.h" 1924269Speter#include "llvm/Support/Path.h" 2024269Speter 2124269Speterusing namespace clang::driver; 2224269Speterusing namespace clang::driver::toolchains; 2324269Speterusing namespace clang::driver::tools; 2424269Speterusing namespace clang; 2524269Speterusing namespace llvm::opt; 2624269Speter 2724269Speterstatic bool isSupportedMCU(const StringRef MCU) { 2824269Speter return llvm::StringSwitch<bool>(MCU) 2924269Speter#define MSP430_MCU(NAME) .Case(NAME, true) 3024269Speter#include "clang/Basic/MSP430Target.def" 3124269Speter .Default(false); 3224269Speter} 3324269Speter 3424269Speterstatic StringRef getSupportedHWMult(const Arg *MCU) { 3524269Speter if (!MCU) 3624269Speter return "none"; 3724269Speter 3824269Speter return llvm::StringSwitch<StringRef>(MCU->getValue()) 3924269Speter#define MSP430_MCU_FEAT(NAME, HWMULT) .Case(NAME, HWMULT) 4024269Speter#include "clang/Basic/MSP430Target.def" 4124269Speter .Default("none"); 4224269Speter} 43116182Sobrien 44116182Sobrienstatic StringRef getHWMultLib(const ArgList &Args) { 45116182Sobrien StringRef HWMult = Args.getLastArgValue(options::OPT_mhwmult_EQ, "auto"); 4624269Speter if (HWMult == "auto") { 4767046Sjasone HWMult = getSupportedHWMult(Args.getLastArg(options::OPT_mmcu_EQ)); 4884812Sjhb } 4924269Speter 50102477Sbde return llvm::StringSwitch<StringRef>(HWMult) 5167353Sjhb .Case("16bit", "-lmul_16") 52102477Sbde .Case("32bit", "-lmul_32") 5324273Speter .Case("f5series", "-lmul_f5") 5424269Speter .Default("-lmul_none"); 5524269Speter} 5624269Speter 5724269Spetervoid msp430::getMSP430TargetFeatures(const Driver &D, const ArgList &Args, 5824269Speter std::vector<StringRef> &Features) { 5924269Speter const Arg *MCU = Args.getLastArg(options::OPT_mmcu_EQ); 6028345Sdyson if (MCU && !isSupportedMCU(MCU->getValue())) { 6128345Sdyson D.Diag(diag::err_drv_clang_unsupported) << MCU->getValue(); 6224269Speter return; 6328345Sdyson } 6428345Sdyson 6528345Sdyson const Arg *HWMultArg = Args.getLastArg(options::OPT_mhwmult_EQ); 6635242Sbde if (!MCU && !HWMultArg) 6728345Sdyson return; 6824269Speter 6929653Sdyson StringRef HWMult = HWMultArg ? HWMultArg->getValue() : "auto"; 7029653Sdyson StringRef SupportedHWMult = getSupportedHWMult(MCU); 7129653Sdyson 7267046Sjasone if (HWMult == "auto") { 7367046Sjasone // 'auto' - deduce hw multiplier support based on mcu name provided. 7467046Sjasone // If no mcu name is provided, assume no hw multiplier is supported. 7567046Sjasone if (!MCU) 7667046Sjasone D.Diag(clang::diag::warn_drv_msp430_hwmult_no_device); 7771320Sjasone HWMult = SupportedHWMult; 7867046Sjasone } 79107414Smckusick 8029653Sdyson if (HWMult == "none") { 8129653Sdyson // 'none' - disable hw multiplier. 8224269Speter Features.push_back("-hwmult16"); 8367046Sjasone Features.push_back("-hwmult32"); 8467046Sjasone Features.push_back("-hwmultf5"); 8567046Sjasone return; 86117660Struckman } 8767046Sjasone 88117660Struckman if (MCU && SupportedHWMult == "none") 8967046Sjasone D.Diag(clang::diag::warn_drv_msp430_hwmult_unsupported) << HWMult; 9028345Sdyson if (MCU && HWMult != SupportedHWMult) 9128345Sdyson D.Diag(clang::diag::warn_drv_msp430_hwmult_mismatch) 9228345Sdyson << SupportedHWMult << HWMult; 9328345Sdyson 9428345Sdyson if (HWMult == "16bit") { 9524269Speter // '16bit' - for 16-bit only hw multiplier. 9628345Sdyson Features.push_back("+hwmult16"); 9728345Sdyson } else if (HWMult == "32bit") { 9842453Seivind // '32bit' - for 16/32-bit hw multiplier. 9942408Seivind Features.push_back("+hwmult32"); 10024269Speter } else if (HWMult == "f5series") { 10134194Sdyson // 'f5series' - for 16/32-bit hw multiplier supported by F5 series mcus. 10228345Sdyson Features.push_back("+hwmultf5"); 10334194Sdyson } else { 10434194Sdyson D.Diag(clang::diag::err_drv_unsupported_option_argument) 10534194Sdyson << HWMultArg->getAsString(Args) << HWMult; 10634194Sdyson } 10734194Sdyson} 10834194Sdyson 10934194Sdyson/// MSP430 Toolchain 11028345SdysonMSP430ToolChain::MSP430ToolChain(const Driver &D, const llvm::Triple &Triple, 11128345Sdyson const ArgList &Args) 11229653Sdyson : Generic_ELF(D, Triple, Args) { 11371576Sjasone 11429653Sdyson StringRef MultilibSuf = ""; 11528345Sdyson 11653090Salc GCCInstallation.init(Triple, Args); 11753090Salc if (GCCInstallation.isValid()) { 11853090Salc MultilibSuf = GCCInstallation.getMultilib().gccSuffix(); 11953090Salc 12053090Salc SmallString<128> GCCBinPath; 12153090Salc llvm::sys::path::append(GCCBinPath, 12253090Salc GCCInstallation.getParentLibPath(), "..", "bin"); 12353090Salc addPathIfExists(D, GCCBinPath, getProgramPaths()); 12453090Salc 12553090Salc SmallString<128> GCCRtPath; 12672200Sbmilekic llvm::sys::path::append(GCCRtPath, 12753090Salc GCCInstallation.getInstallPath(), MultilibSuf); 12853090Salc addPathIfExists(D, GCCRtPath, getFilePaths()); 12953090Salc } 13072200Sbmilekic 13128345Sdyson SmallString<128> SysRootDir(computeSysRoot()); 13228345Sdyson llvm::sys::path::append(SysRootDir, "lib", MultilibSuf); 13324269Speter addPathIfExists(D, SysRootDir, getFilePaths()); 13453090Salc} 13528345Sdyson 13628345Sdysonstd::string MSP430ToolChain::computeSysRoot() const { 13724269Speter if (!getDriver().SysRoot.empty()) 13828345Sdyson return getDriver().SysRoot; 139107414Smckusick 140107414Smckusick SmallString<128> Dir; 14134194Sdyson if (GCCInstallation.isValid()) 14228345Sdyson llvm::sys::path::append(Dir, GCCInstallation.getParentLibPath(), "..", 143112106Sjhb GCCInstallation.getTriple().str()); 144132587Srwatson else 14566615Sjasone llvm::sys::path::append(Dir, getDriver().Dir, "..", getTriple().str()); 14666615Sjasone 14728345Sdyson return Dir.str(); 14828345Sdyson} 14928345Sdyson 15028345Sdysonvoid MSP430ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, 15129653Sdyson ArgStringList &CC1Args) const { 15229653Sdyson if (DriverArgs.hasArg(options::OPT_nostdinc) || 15329653Sdyson DriverArgs.hasArg(options::OPT_nostdlibinc)) 15429653Sdyson return; 15529653Sdyson 15628345Sdyson SmallString<128> Dir(computeSysRoot()); 15734194Sdyson llvm::sys::path::append(Dir, "include"); 15828345Sdyson addSystemInclude(DriverArgs, CC1Args, Dir.str()); 15928345Sdyson} 16028345Sdyson 16169432Sjakevoid MSP430ToolChain::addClangTargetOptions(const ArgList &DriverArgs, 16288318Sdillon ArgStringList &CC1Args, 16388318Sdillon Action::OffloadKind) const { 16434194Sdyson CC1Args.push_back("-nostdsysteminc"); 16528345Sdyson 16634194Sdyson const auto *MCUArg = DriverArgs.getLastArg(options::OPT_mmcu_EQ); 16734194Sdyson if (!MCUArg) 16834194Sdyson return; 16934194Sdyson 17034194Sdyson const StringRef MCU = MCUArg->getValue(); 17134194Sdyson if (MCU.startswith("msp430i")) { 17228345Sdyson // 'i' should be in lower case as it's defined in TI MSP430-GCC headers 17334194Sdyson CC1Args.push_back(DriverArgs.MakeArgString( 17428345Sdyson "-D__MSP430i" + MCU.drop_front(7).upper() + "__")); 17534194Sdyson } else { 17628345Sdyson CC1Args.push_back(DriverArgs.MakeArgString("-D__" + MCU.upper() + "__")); 17728345Sdyson } 178107414Smckusick} 179107414Smckusick 180107414SmckusickTool *MSP430ToolChain::buildLinker() const { 181107414Smckusick return new tools::msp430::Linker(*this); 182107414Smckusick} 183107414Smckusick 184107414Smckusickvoid msp430::Linker::ConstructJob(Compilation &C, const JobAction &JA, 18528345Sdyson const InputInfo &Output, 18634194Sdyson const InputInfoList &Inputs, 18728345Sdyson const ArgList &Args, 18828345Sdyson const char *LinkingOutput) const { 18928345Sdyson const ToolChain &ToolChain = getToolChain(); 19024269Speter const Driver &D = ToolChain.getDriver(); 19124269Speter std::string Linker = ToolChain.GetProgramPath(getShortName()); 19224269Speter ArgStringList CmdArgs; 19324269Speter 19424269Speter if (!D.SysRoot.empty()) 19524269Speter CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); 19624269Speter 19724269Speter Args.AddAllArgs(CmdArgs, options::OPT_L); 19842900Seivind ToolChain.AddFilePathLibArgs(Args, CmdArgs); 19983366Sjulian 20042900Seivind if (!Args.hasArg(options::OPT_T)) { 20183366Sjulian if (const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ)) 20242900Seivind CmdArgs.push_back( 20327894Sfsmp Args.MakeArgString("-T" + StringRef(MCUArg->getValue()) + ".ld")); 20424269Speter } else { 20566615Sjasone Args.AddAllArgs(CmdArgs, options::OPT_T); 20683366Sjulian } 20742900Seivind 20842900Seivind if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 20942900Seivind CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); 21042900Seivind CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); 21142900Seivind } 21224269Speter 21324269Speter AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); 214110414Sjulian 21572227Sjhb CmdArgs.push_back("--start-group"); 21624269Speter CmdArgs.push_back(Args.MakeArgString(getHWMultLib(Args))); 217112106Sjhb CmdArgs.push_back("-lgcc"); 21866615Sjasone if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { 21983366Sjulian CmdArgs.push_back("-lc"); 22066615Sjasone CmdArgs.push_back("-lcrt"); 22124269Speter CmdArgs.push_back("-lnosys"); 22283366Sjulian } 223110414Sjulian CmdArgs.push_back("--end-group"); 22428393Sdyson 225110414Sjulian if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { 22628345Sdyson CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); 227111463Sjeff CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); 228111463Sjeff } 22975740Salfred CmdArgs.push_back("-o"); 23076100Salfred CmdArgs.push_back(Output.getFilename()); 23172200Sbmilekic C.addCommand(llvm::make_unique<Command>(JA, *this, Args.MakeArgString(Linker), 23275740Salfred CmdArgs, Inputs)); 23328345Sdyson} 234111463Sjeff