Index: cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td +++ cfe/trunk/include/clang/Basic/DiagnosticDriverKinds.td @@ -414,4 +414,15 @@ "-ftrivial-auto-var-init=zero hasn't been enabled. Enable it at your own peril for benchmarking purpose only with " "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">; +def warn_drv_msp430_hwmult_unsupported : Warning<"the given MCU does not " + "support hardware multiply, but -mhwmult is set to %0.">, + InGroup; +def warn_drv_msp430_hwmult_mismatch : Warning<"the given MCU supports %0 " + "hardware multiply, but -mhwmult is set to %1.">, + InGroup; +def warn_drv_msp430_hwmult_no_device : Warning<"no MCU device specified, but " + "'-mhwmult' is set to 'auto', assuming no hardware multiply. Use -mmcu to " + "specify a MSP430 device, or -mhwmult to set hardware multiply type " + "explicitly.">, InGroup; + } Index: cfe/trunk/include/clang/Basic/MSP430Target.def =================================================================== --- cfe/trunk/include/clang/Basic/MSP430Target.def +++ cfe/trunk/include/clang/Basic/MSP430Target.def @@ -0,0 +1,247 @@ +//===--- MSP430Target.def - MSP430 Feature/Processor Database----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the MSP430 devices and their features. +// +//===----------------------------------------------------------------------===// + +#ifndef MSP430_MCU_FEAT +#define MSP430_MCU_FEAT(NAME, HWMULT) MSP430_MCU(NAME) +#endif + +#ifndef MSP430_MCU +#define MSP430_MCU(NAME) +#endif + +MSP430_MCU("msp430c111") +MSP430_MCU("msp430c1111") +MSP430_MCU("msp430c112") +MSP430_MCU("msp430c1121") +MSP430_MCU("msp430c1331") +MSP430_MCU("msp430c1351") +MSP430_MCU("msp430e112") +MSP430_MCU("msp430f110") +MSP430_MCU("msp430f1101") +MSP430_MCU("msp430f1101a") +MSP430_MCU("msp430f1111") +MSP430_MCU("msp430f1111a") +MSP430_MCU("msp430f112") +MSP430_MCU("msp430f1121") +MSP430_MCU("msp430f1121a") +MSP430_MCU("msp430f1122") +MSP430_MCU("msp430f1132") +MSP430_MCU("msp430f122") +MSP430_MCU("msp430f1222") +MSP430_MCU("msp430f123") +MSP430_MCU("msp430f1232") +MSP430_MCU("msp430f133") +MSP430_MCU("msp430f135") +MSP430_MCU("msp430f155") +MSP430_MCU("msp430f156") +MSP430_MCU("msp430f157") +MSP430_MCU("msp430p112") +MSP430_MCU("msp430f2001") +MSP430_MCU("msp430f2011") +MSP430_MCU("msp430f2002") +MSP430_MCU("msp430f2012") +MSP430_MCU("msp430f2003") +MSP430_MCU("msp430f2013") +MSP430_MCU("msp430f2101") +MSP430_MCU("msp430f2111") +MSP430_MCU("msp430f2121") +MSP430_MCU("msp430f2131") +MSP430_MCU("msp430f2112") +MSP430_MCU("msp430f2122") +MSP430_MCU("msp430f2132") +MSP430_MCU("msp430f2232") +MSP430_MCU("msp430f2252") +MSP430_MCU("msp430f2272") +MSP430_MCU("msp430f2234") +MSP430_MCU("msp430f2254") +MSP430_MCU("msp430f2274") +MSP430_MCU("msp430g2211") +MSP430_MCU("msp430g2201") +MSP430_MCU("msp430g2111") +MSP430_MCU("msp430g2101") +MSP430_MCU("msp430g2001") +MSP430_MCU("msp430g2231") +MSP430_MCU("msp430g2221") +MSP430_MCU("msp430g2131") +MSP430_MCU("msp430g2121") +MSP430_MCU("msp430g2102") +MSP430_MCU("msp430g2202") +MSP430_MCU("msp430g2302") +MSP430_MCU("msp430g2402") +MSP430_MCU("msp430g2132") +MSP430_MCU("msp430g2232") +MSP430_MCU("msp430g2332") +MSP430_MCU("msp430g2432") +MSP430_MCU("msp430g2112") +MSP430_MCU("msp430g2212") +MSP430_MCU("msp430g2312") +MSP430_MCU("msp430g2412") +MSP430_MCU("msp430g2152") +MSP430_MCU("msp430g2252") +MSP430_MCU("msp430g2352") +MSP430_MCU("msp430g2452") +MSP430_MCU("msp430g2113") +MSP430_MCU("msp430g2213") +MSP430_MCU("msp430g2313") +MSP430_MCU("msp430g2413") +MSP430_MCU("msp430g2513") +MSP430_MCU("msp430g2153") +MSP430_MCU("msp430g2253") +MSP430_MCU("msp430g2353") +MSP430_MCU("msp430g2453") +MSP430_MCU("msp430g2553") +MSP430_MCU("msp430g2203") +MSP430_MCU("msp430g2303") +MSP430_MCU("msp430g2403") +MSP430_MCU("msp430g2233") +MSP430_MCU("msp430g2333") +MSP430_MCU("msp430g2433") +MSP430_MCU("msp430g2533") +MSP430_MCU("msp430tch5e") +MSP430_MCU("msp430g2444") +MSP430_MCU("msp430g2544") +MSP430_MCU("msp430g2744") +MSP430_MCU("msp430g2755") +MSP430_MCU("msp430g2855") +MSP430_MCU("msp430g2955") +MSP430_MCU("msp430g2230") +MSP430_MCU("msp430g2210") +MSP430_MCU("msp430c311s") +MSP430_MCU("msp430c312") +MSP430_MCU("msp430c313") +MSP430_MCU("msp430c314") +MSP430_MCU("msp430c315") +MSP430_MCU("msp430c323") +MSP430_MCU("msp430c325") +MSP430_MCU("msp430c412") +MSP430_MCU("msp430c413") +MSP430_MCU("msp430e313") +MSP430_MCU("msp430e315") +MSP430_MCU("msp430e325") +MSP430_MCU("msp430p313") +MSP430_MCU("msp430p315") +MSP430_MCU("msp430p315s") +MSP430_MCU("msp430p325") +MSP430_MCU("msp430f412") +MSP430_MCU("msp430f413") +MSP430_MCU("msp430f415") +MSP430_MCU("msp430f417") +MSP430_MCU("msp430f4132") +MSP430_MCU("msp430f4152") +MSP430_MCU("msp430f435") +MSP430_MCU("msp430f436") +MSP430_MCU("msp430f437") +MSP430_MCU("msp430f4351") +MSP430_MCU("msp430f4361") +MSP430_MCU("msp430f4371") +MSP430_MCU("msp430fe423") +MSP430_MCU("msp430fe425") +MSP430_MCU("msp430fe427") +MSP430_MCU("msp430fe423a") +MSP430_MCU("msp430fe425a") +MSP430_MCU("msp430fe427a") +MSP430_MCU("msp430fe4232") +MSP430_MCU("msp430fe4242") +MSP430_MCU("msp430fe4252") +MSP430_MCU("msp430fe4272") +MSP430_MCU("msp430f4250") +MSP430_MCU("msp430f4260") +MSP430_MCU("msp430f4270") +MSP430_MCU("msp430fg4250") +MSP430_MCU("msp430fg4260") +MSP430_MCU("msp430fg4270") +MSP430_MCU("msp430fw423") +MSP430_MCU("msp430fw425") +MSP430_MCU("msp430fw427") +MSP430_MCU("msp430fw428") +MSP430_MCU("msp430fw429") +MSP430_MCU("msp430fg437") +MSP430_MCU("msp430fg438") +MSP430_MCU("msp430fg439") +MSP430_MCU("msp430f438") +MSP430_MCU("msp430f439") +MSP430_MCU("msp430f477") +MSP430_MCU("msp430f478") +MSP430_MCU("msp430f479") +MSP430_MCU("msp430fg477") +MSP430_MCU("msp430fg478") +MSP430_MCU("msp430fg479") + +// With 16-bit hardware multiplier +MSP430_MCU_FEAT("msp430f147", "16bit") +MSP430_MCU_FEAT("msp430f148", "16bit") +MSP430_MCU_FEAT("msp430f149", "16bit") +MSP430_MCU_FEAT("msp430f1471", "16bit") +MSP430_MCU_FEAT("msp430f1481", "16bit") +MSP430_MCU_FEAT("msp430f1491", "16bit") +MSP430_MCU_FEAT("msp430f167", "16bit") +MSP430_MCU_FEAT("msp430f168", "16bit") +MSP430_MCU_FEAT("msp430f169", "16bit") +MSP430_MCU_FEAT("msp430f1610", "16bit") +MSP430_MCU_FEAT("msp430f1611", "16bit") +MSP430_MCU_FEAT("msp430f1612", "16bit") +MSP430_MCU_FEAT("msp430c336", "16bit") +MSP430_MCU_FEAT("msp430c337", "16bit") +MSP430_MCU_FEAT("msp430e337", "16bit") +MSP430_MCU_FEAT("msp430p337", "16bit") +MSP430_MCU_FEAT("msp430f423", "16bit") +MSP430_MCU_FEAT("msp430f425", "16bit") +MSP430_MCU_FEAT("msp430f427", "16bit") +MSP430_MCU_FEAT("msp430f423a", "16bit") +MSP430_MCU_FEAT("msp430f425a", "16bit") +MSP430_MCU_FEAT("msp430f427a", "16bit") +MSP430_MCU_FEAT("msp430f4481", "16bit") +MSP430_MCU_FEAT("msp430f4491", "16bit") +MSP430_MCU_FEAT("msp430f447", "16bit") +MSP430_MCU_FEAT("msp430f448", "16bit") +MSP430_MCU_FEAT("msp430f449", "16bit") +MSP430_MCU_FEAT("msp430f2330", "16bit") +MSP430_MCU_FEAT("msp430f2350", "16bit") +MSP430_MCU_FEAT("msp430f2370", "16bit") +MSP430_MCU_FEAT("msp430f233", "16bit") +MSP430_MCU_FEAT("msp430f235", "16bit") +MSP430_MCU_FEAT("msp430f247", "16bit") +MSP430_MCU_FEAT("msp430f248", "16bit") +MSP430_MCU_FEAT("msp430f249", "16bit") +MSP430_MCU_FEAT("msp430f2410", "16bit") +MSP430_MCU_FEAT("msp430f2471", "16bit") +MSP430_MCU_FEAT("msp430f2481", "16bit") +MSP430_MCU_FEAT("msp430f2491", "16bit") +MSP430_MCU_FEAT("msp430i2020", "16bit") +MSP430_MCU_FEAT("msp430i2021", "16bit") +MSP430_MCU_FEAT("msp430i2030", "16bit") +MSP430_MCU_FEAT("msp430i2031", "16bit") +MSP430_MCU_FEAT("msp430i2040", "16bit") +MSP430_MCU_FEAT("msp430i2041", "16bit") +MSP430_MCU_FEAT("msp430afe221", "16bit") +MSP430_MCU_FEAT("msp430afe231", "16bit") +MSP430_MCU_FEAT("msp430afe251", "16bit") +MSP430_MCU_FEAT("msp430afe222", "16bit") +MSP430_MCU_FEAT("msp430afe232", "16bit") +MSP430_MCU_FEAT("msp430afe252", "16bit") +MSP430_MCU_FEAT("msp430afe223", "16bit") +MSP430_MCU_FEAT("msp430afe233", "16bit") +MSP430_MCU_FEAT("msp430afe253", "16bit") + +// With 32 Bit Hardware Multiplier +MSP430_MCU_FEAT("msp430f4783", "32bit") +MSP430_MCU_FEAT("msp430f4793", "32bit") +MSP430_MCU_FEAT("msp430f4784", "32bit") +MSP430_MCU_FEAT("msp430f4794", "32bit") + +// Generic MSUs +MSP430_MCU("msp430") +MSP430_MCU("msp430i2xxgeneric") + +#undef MSP430_MCU +#undef MSP430_MCU_FEAT Index: cfe/trunk/include/clang/Driver/Options.td =================================================================== --- cfe/trunk/include/clang/Driver/Options.td +++ cfe/trunk/include/clang/Driver/Options.td @@ -2035,6 +2035,7 @@ def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group; def mfpu_EQ : Joined<["-"], "mfpu=">, Group; def mhwdiv_EQ : Joined<["-"], "mhwdiv=">, Group; +def mhwmult_EQ : Joined<["-"], "mhwmult=">, Group; def mglobal_merge : Flag<["-"], "mglobal-merge">, Group, Flags<[CC1Option]>, HelpText<"Enable merging of globals">; def mhard_float : Flag<["-"], "mhard-float">, Group; Index: cfe/trunk/include/clang/module.modulemap =================================================================== --- cfe/trunk/include/clang/module.modulemap +++ cfe/trunk/include/clang/module.modulemap @@ -50,6 +50,7 @@ textual header "Basic/CodeGenOptions.def" textual header "Basic/DiagnosticOptions.def" textual header "Basic/Features.def" + textual header "Basic/MSP430Target.def" textual header "Basic/LangOptions.def" textual header "Basic/OpenCLExtensions.def" textual header "Basic/OpenCLImageTypes.def" Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp =================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp @@ -137,10 +137,12 @@ // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. if (LangOpts.Sanitize.has(SanitizerKind::Thread) || - (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) + (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) { + fprintf(stderr, "TBAA enabled\n"); TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(), getCXXABI().getMangleContext())); - + } + // If debug info or coverage generation is enabled, create the CGDebugInfo // object. if (CodeGenOpts.getDebugInfo() != codegenoptions::NoDebugInfo || Index: cfe/trunk/lib/Driver/CMakeLists.txt =================================================================== --- cfe/trunk/lib/Driver/CMakeLists.txt +++ cfe/trunk/lib/Driver/CMakeLists.txt @@ -53,6 +53,7 @@ ToolChains/MipsLinux.cpp ToolChains/MinGW.cpp ToolChains/Minix.cpp + ToolChains/MSP430.cpp ToolChains/MSVC.cpp ToolChains/Myriad.cpp ToolChains/NaCl.cpp Index: cfe/trunk/lib/Driver/Driver.cpp =================================================================== --- cfe/trunk/lib/Driver/Driver.cpp +++ cfe/trunk/lib/Driver/Driver.cpp @@ -29,6 +29,7 @@ #include "ToolChains/Hurd.h" #include "ToolChains/Lanai.h" #include "ToolChains/Linux.h" +#include "ToolChains/MSP430.h" #include "ToolChains/MSVC.h" #include "ToolChains/MinGW.h" #include "ToolChains/Minix.h" @@ -4637,6 +4638,10 @@ case llvm::Triple::avr: TC = llvm::make_unique(*this, Target, Args); break; + case llvm::Triple::msp430: + TC = + llvm::make_unique(*this, Target, Args); + break; case llvm::Triple::riscv32: case llvm::Triple::riscv64: TC = llvm::make_unique(*this, Target, Args); Index: cfe/trunk/lib/Driver/ToolChains/Clang.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/Clang.cpp +++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp @@ -19,6 +19,7 @@ #include "AMDGPU.h" #include "CommonArgs.h" #include "Hexagon.h" +#include "MSP430.h" #include "InputInfo.h" #include "PS4CPU.h" #include "clang/Basic/CharInfo.h" @@ -364,6 +365,8 @@ case llvm::Triple::amdgcn: amdgpu::getAMDGPUTargetFeatures(D, Args, Features); break; + case llvm::Triple::msp430: + msp430::getMSP430TargetFeatures(D, Args, Features); } // Find the last of each feature. Index: cfe/trunk/lib/Driver/ToolChains/Gnu.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/Gnu.cpp +++ cfe/trunk/lib/Driver/ToolChains/Gnu.cpp @@ -878,6 +878,10 @@ return Arch == llvm::Triple::riscv32 || Arch == llvm::Triple::riscv64; } +static bool isMSP430(llvm::Triple::ArchType Arch) { + return Arch == llvm::Triple::msp430; +} + static Multilib makeMultilib(StringRef commonSuffix) { return Multilib(commonSuffix, commonSuffix, commonSuffix); } @@ -1423,6 +1427,26 @@ Result.Multilibs = AndroidArmMultilibs; } +static bool findMSP430Multilibs(const Driver &D, + const llvm::Triple &TargetTriple, + StringRef Path, const ArgList &Args, + DetectedMultilibs &Result) { + FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); + Multilib MSP430Multilib = makeMultilib("/430"); + // FIXME: when clang starts to support msp430x ISA additional logic + // to select between multilib must be implemented + // Multilib MSP430xMultilib = makeMultilib("/large"); + + Result.Multilibs.push_back(MSP430Multilib); + Result.Multilibs.FilterOut(NonExistent); + + Multilib::flags_list Flags; + if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) + return true; + + return false; +} + static void findRISCVMultilibs(const Driver &D, const llvm::Triple &TargetTriple, StringRef Path, const ArgList &Args, DetectedMultilibs &Result) { @@ -1911,6 +1935,9 @@ static const char *const MIPSN32ELTriples[] = { "mips64el-linux-gnuabin32", "mipsisa64r6el-linux-gnuabin32"}; + static const char *const MSP430LibDirs[] = {"/lib"}; + static const char *const MSP430Triples[] = {"msp430-elf"}; + static const char *const PPCLibDirs[] = {"/lib32", "/lib"}; static const char *const PPCTriples[] = { "powerpc-linux-gnu", "powerpc-unknown-linux-gnu", "powerpc-linux-gnuspe", @@ -2135,6 +2162,10 @@ BiarchTripleAliases.append(begin(MIPSN32ELTriples), end(MIPSN32ELTriples)); BiarchTripleAliases.append(begin(MIPSTriples), end(MIPSTriples)); break; + case llvm::Triple::msp430: + LibDirs.append(begin(MSP430LibDirs), end(MSP430LibDirs)); + TripleAliases.append(begin(MSP430Triples), end(MSP430Triples)); + break; case llvm::Triple::ppc: LibDirs.append(begin(PPCLibDirs), end(PPCLibDirs)); TripleAliases.append(begin(PPCTriples), end(PPCTriples)); @@ -2206,6 +2237,8 @@ return false; } else if (isRISCV(TargetArch)) { findRISCVMultilibs(D, TargetTriple, Path, Args, Detected); + } else if (isMSP430(TargetArch)) { + findMSP430Multilibs(D, TargetTriple, Path, Args, Detected); } else if (!findBiarchMultilibs(D, TargetTriple, Path, Args, NeedsBiarchSuffix, Detected)) { return false; @@ -2474,6 +2507,7 @@ case llvm::Triple::mipsel: case llvm::Triple::mips64: case llvm::Triple::mips64el: + case llvm::Triple::msp430: return true; case llvm::Triple::sparc: case llvm::Triple::sparcel: Index: cfe/trunk/lib/Driver/ToolChains/MSP430.h =================================================================== --- cfe/trunk/lib/Driver/ToolChains/MSP430.h +++ cfe/trunk/lib/Driver/ToolChains/MSP430.h @@ -0,0 +1,71 @@ +//===--- MSP430.h - MSP430-specific Tool Helpers ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSP430_H +#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSP430_H + +#include "Gnu.h" +#include "InputInfo.h" +#include "clang/Driver/Driver.h" +#include "clang/Driver/DriverDiagnostic.h" +#include "clang/Driver/Tool.h" +#include "clang/Driver/ToolChain.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Option/Option.h" + +#include +#include + +namespace clang { +namespace driver { +namespace toolchains { + +class LLVM_LIBRARY_VISIBILITY MSP430ToolChain : public Generic_ELF { +public: + MSP430ToolChain(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args, + Action::OffloadKind) const override; + +protected: + Tool *buildLinker() const override; + +private: + std::string computeSysRoot() const; +}; + +} // end namespace toolchains + +namespace tools { +namespace msp430 { + +class LLVM_LIBRARY_VISIBILITY Linker : public GnuTool { +public: + Linker(const ToolChain &TC) + : GnuTool("MSP430::Linker", "msp430-elf-ld", TC) {} + bool hasIntegratedCPP() const override { return false; } + bool isLinkJob() 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; +}; + +void getMSP430TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, + std::vector &Features); +} // end namespace msp430 +} // end namespace tools +} // end namespace driver +} // end namespace clang + +#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_MSP430_H Index: cfe/trunk/lib/Driver/ToolChains/MSP430.cpp =================================================================== --- cfe/trunk/lib/Driver/ToolChains/MSP430.cpp +++ cfe/trunk/lib/Driver/ToolChains/MSP430.cpp @@ -0,0 +1,233 @@ +//===--- MSP430.cpp - MSP430 Helpers for Tools ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MSP430.h" +#include "CommonArgs.h" +#include "Gnu.h" +#include "InputInfo.h" +#include "clang/Driver/Compilation.h" +#include "clang/Driver/Multilib.h" +#include "clang/Driver/Options.h" +#include "llvm/Option/ArgList.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace clang::driver; +using namespace clang::driver::toolchains; +using namespace clang::driver::tools; +using namespace clang; +using namespace llvm::opt; + +static bool isSupportedMCU(const StringRef MCU) { + return llvm::StringSwitch(MCU) +#define MSP430_MCU(NAME) .Case(NAME, true) +#include "clang/Basic/MSP430Target.def" + .Default(false); +} + +static StringRef getSupportedHWMult(const Arg *MCU) { + if (!MCU) + return "none"; + + return llvm::StringSwitch(MCU->getValue()) +#define MSP430_MCU_FEAT(NAME, HWMULT) .Case(NAME, HWMULT) +#include "clang/Basic/MSP430Target.def" + .Default("none"); +} + +static StringRef getHWMultLib(const ArgList &Args) { + StringRef HWMult = Args.getLastArgValue(options::OPT_mhwmult_EQ, "auto"); + if (HWMult == "auto") { + HWMult = getSupportedHWMult(Args.getLastArg(options::OPT_mmcu_EQ)); + } + + return llvm::StringSwitch(HWMult) + .Case("16bit", "-lmul_16") + .Case("32bit", "-lmul_32") + .Case("f5series", "-lmul_f5") + .Default("-lmul_none"); +} + +void msp430::getMSP430TargetFeatures(const Driver &D, const ArgList &Args, + std::vector &Features) { + const Arg *MCU = Args.getLastArg(options::OPT_mmcu_EQ); + if (MCU && !isSupportedMCU(MCU->getValue())) { + D.Diag(diag::err_drv_clang_unsupported) << MCU->getValue(); + return; + } + + const Arg *HWMultArg = Args.getLastArg(options::OPT_mhwmult_EQ); + if (!MCU && !HWMultArg) + return; + + StringRef HWMult = HWMultArg ? HWMultArg->getValue() : "auto"; + StringRef SupportedHWMult = getSupportedHWMult(MCU); + + if (HWMult == "auto") { + // 'auto' - deduce hw multiplier support based on mcu name provided. + // If no mcu name is provided, assume no hw multiplier is supported. + if (!MCU) + D.Diag(clang::diag::warn_drv_msp430_hwmult_no_device); + HWMult = SupportedHWMult; + } + + if (HWMult == "none") { + // 'none' - disable hw multiplier. + Features.push_back("-hwmult16"); + Features.push_back("-hwmult32"); + Features.push_back("-hwmultf5"); + return; + } + + if (MCU && SupportedHWMult == "none") + D.Diag(clang::diag::warn_drv_msp430_hwmult_unsupported) << HWMult; + if (MCU && HWMult != SupportedHWMult) + D.Diag(clang::diag::warn_drv_msp430_hwmult_mismatch) + << SupportedHWMult << HWMult; + + if (HWMult == "16bit") { + // '16bit' - for 16-bit only hw multiplier. + Features.push_back("+hwmult16"); + } else if (HWMult == "32bit") { + // '32bit' - for 16/32-bit hw multiplier. + Features.push_back("+hwmult32"); + } else if (HWMult == "f5series") { + // 'f5series' - for 16/32-bit hw multiplier supported by F5 series mcus. + Features.push_back("+hwmultf5"); + } else { + D.Diag(clang::diag::err_drv_unsupported_option_argument) + << HWMultArg->getAsString(Args) << HWMult; + } +} + +/// MSP430 Toolchain +MSP430ToolChain::MSP430ToolChain(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : Generic_ELF(D, Triple, Args) { + + StringRef MultilibSuf = ""; + + GCCInstallation.init(Triple, Args); + if (GCCInstallation.isValid()) { + MultilibSuf = GCCInstallation.getMultilib().gccSuffix(); + + SmallString<128> GCCBinPath; + llvm::sys::path::append(GCCBinPath, + GCCInstallation.getParentLibPath(), "..", "bin"); + addPathIfExists(D, GCCBinPath, getProgramPaths()); + + SmallString<128> GCCRtPath; + llvm::sys::path::append(GCCRtPath, + GCCInstallation.getInstallPath(), MultilibSuf); + addPathIfExists(D, GCCRtPath, getFilePaths()); + } + + SmallString<128> SysRootDir(computeSysRoot()); + llvm::sys::path::append(SysRootDir, "lib", MultilibSuf); + addPathIfExists(D, SysRootDir, getFilePaths()); +} + +std::string MSP430ToolChain::computeSysRoot() const { + if (!getDriver().SysRoot.empty()) + return getDriver().SysRoot; + + SmallString<128> Dir; + if (GCCInstallation.isValid()) + llvm::sys::path::append(Dir, GCCInstallation.getParentLibPath(), "..", + GCCInstallation.getTriple().str()); + else + llvm::sys::path::append(Dir, getDriver().Dir, "..", getTriple().str()); + + return Dir.str(); +} + +void MSP430ToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { + if (DriverArgs.hasArg(options::OPT_nostdinc) || + DriverArgs.hasArg(options::OPT_nostdlibinc)) + return; + + SmallString<128> Dir(computeSysRoot()); + llvm::sys::path::append(Dir, "include"); + addSystemInclude(DriverArgs, CC1Args, Dir.str()); +} + +void MSP430ToolChain::addClangTargetOptions(const ArgList &DriverArgs, + ArgStringList &CC1Args, + Action::OffloadKind) const { + CC1Args.push_back("-nostdsysteminc"); + + const auto *MCUArg = DriverArgs.getLastArg(options::OPT_mmcu_EQ); + if (!MCUArg) + return; + + const StringRef MCU = MCUArg->getValue(); + if (MCU.startswith("msp430i")) { + // 'i' should be in lower case as it's defined in TI MSP430-GCC headers + CC1Args.push_back(DriverArgs.MakeArgString( + "-D__MSP430i" + MCU.drop_front(7).upper() + "__")); + } else { + CC1Args.push_back(DriverArgs.MakeArgString("-D__" + MCU.upper() + "__")); + } +} + +Tool *MSP430ToolChain::buildLinker() const { + return new tools::msp430::Linker(*this); +} + +void msp430::Linker::ConstructJob(Compilation &C, const JobAction &JA, + const InputInfo &Output, + const InputInfoList &Inputs, + const ArgList &Args, + const char *LinkingOutput) const { + const ToolChain &ToolChain = getToolChain(); + const Driver &D = ToolChain.getDriver(); + std::string Linker = ToolChain.GetProgramPath(getShortName()); + ArgStringList CmdArgs; + + if (!D.SysRoot.empty()) + CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); + + Args.AddAllArgs(CmdArgs, options::OPT_L); + ToolChain.AddFilePathLibArgs(Args, CmdArgs); + + if (!Args.hasArg(options::OPT_T)) { + if (const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ)) + CmdArgs.push_back( + Args.MakeArgString("-T" + StringRef(MCUArg->getValue()) + ".ld")); + } else { + Args.AddAllArgs(CmdArgs, options::OPT_T); + } + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crt0.o"))); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtbegin.o"))); + } + + AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); + + CmdArgs.push_back("--start-group"); + CmdArgs.push_back(Args.MakeArgString(getHWMultLib(Args))); + CmdArgs.push_back("-lgcc"); + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { + CmdArgs.push_back("-lc"); + CmdArgs.push_back("-lcrt"); + CmdArgs.push_back("-lnosys"); + } + CmdArgs.push_back("--end-group"); + + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o"))); + CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); + } + CmdArgs.push_back("-o"); + CmdArgs.push_back(Output.getFilename()); + C.addCommand(llvm::make_unique(JA, *this, Args.MakeArgString(Linker), + CmdArgs, Inputs)); +} Index: cfe/trunk/test/Driver/msp430-hwmult.c =================================================================== --- cfe/trunk/test/Driver/msp430-hwmult.c +++ cfe/trunk/test/Driver/msp430-hwmult.c @@ -0,0 +1,42 @@ +// Test that different values of -mhwmult pick correct +// MSP430 hwmult target-feature(s). + +// RUN: %clang -### -target msp430 %s 2>&1 | FileCheck %s +// RUN: %clang -### -target msp430 %s -mhwmult=auto 2>&1 | FileCheck %s +// CHECK-NOT: "-target-feature" "+hwmult16" +// CHECK-NOT: "-target-feature" "+hwmult32" +// CHECK-NOT: "-target-feature" "+hwmultf5" + +// RUN: %clang -### -target msp430 %s -mhwmult=none 2>&1 | FileCheck --check-prefix=CHECK-NONE %s +// RUN: %clang -### -target msp430 %s -mhwmult=none -mmcu=msp430f147 2>&1 | FileCheck --check-prefix=CHECK-NONE %s +// RUN: %clang -### -target msp430 %s -mhwmult=none -mmcu=msp430f4783 2>&1 | FileCheck --check-prefix=CHECK-NONE %s +// CHECK-NONE: "-target-feature" "-hwmult16" +// CHECK-NONE: "-target-feature" "-hwmult32" +// CHECK-NONE: "-target-feature" "-hwmultf5" + +// RUN: %clang -### -target msp430 %s -mhwmult=16bit 2>&1 | FileCheck --check-prefix=CHECK-16 %s +// CHECK-16: "-target-feature" "+hwmult16" + +// RUN: %clang -### -target msp430 %s -mhwmult=32bit 2>&1 | FileCheck --check-prefix=CHECK-32 %s +// CHECK-32: "-target-feature" "+hwmult32" + +// RUN: %clang -### -target msp430 %s -mhwmult=f5series 2>&1 | FileCheck --check-prefix=CHECK-F5 %s +// CHECK-F5: "-target-feature" "+hwmultf5" + +// RUN: %clang -### -target msp430 %s -mhwmult=rrr 2>&1 | FileCheck --check-prefix=INVL-ARG %s +// INVL-ARG: error: unsupported argument 'rrr' to option '-mhwmult=rrr' + +// RUN: %clang -### -target msp430 %s -mhwmult=auto 2>&1 | FileCheck --check-prefix=WRN-NODEV %s +// WRN-NODEV: warning: no MCU device specified, but '-mhwmult' is set to 'auto', +// assuming no hardware multiply. Use -mmcu to specify a MSP430 device, +// or -mhwmult to set hardware multiply type explicitly. + +// RUN: %clang -### -target msp430 %s -mhwmult=16bit -mmcu=msp430c111 2>&1 | FileCheck --check-prefix=WRN-UNSUP %s +// RUN: %clang -### -target msp430 %s -mhwmult=32bit -mmcu=msp430c111 2>&1 | FileCheck --check-prefix=WRN-UNSUP %s +// RUN: %clang -### -target msp430 %s -mhwmult=f5series -mmcu=msp430c111 2>&1 | FileCheck --check-prefix=WRN-UNSUP %s +// WRN-UNSUP: warning: the given MCU does not support hardware multiply, but -mhwmult is set to + +// RUN: %clang -### -target msp430 %s -mhwmult=16bit -mmcu=msp430f4783 2>&1 | FileCheck --check-prefix=WRN-MISMCH %s +// RUN: %clang -### -target msp430 %s -mhwmult=32bit -mmcu=msp430f147 2>&1 | FileCheck --check-prefix=WRN-MISMCH %s +// RUN: %clang -### -target msp430 %s -mhwmult=f5series -mmcu=msp430f4783 2>&1 | FileCheck --check-prefix=WRN-MISMCH %s +// WRN-MISMCH: warning: the given MCU supports {{.*}} hardware multiply, but -mhwmult is set to {{.*}} Index: cfe/trunk/test/Driver/msp430-mmcu.c =================================================================== --- cfe/trunk/test/Driver/msp430-mmcu.c +++ cfe/trunk/test/Driver/msp430-mmcu.c @@ -0,0 +1,16 @@ +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430c111 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-C111 %s + +// MSP430-C111: clang{{.*}} "-cc1" {{.*}} "-D__MSP430C111__" +// MSP430-C111: msp430-elf-ld{{.*}} "-Tmsp430c111.ld" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430i2020 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-I2020 %s + +// MSP430-I2020: clang{{.*}} "-cc1" {{.*}} "-D__MSP430i2020__" +// MSP430-I2020: msp430-elf-ld{{.*}} "-Tmsp430i2020.ld" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=not-a-mcu 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-UNSUP %s + +// MSP430-UNSUP: error: the clang compiler does not support 'not-a-mcu' Index: cfe/trunk/test/Driver/msp430-toolchain.c =================================================================== --- cfe/trunk/test/Driver/msp430-toolchain.c +++ cfe/trunk/test/Driver/msp430-toolchain.c @@ -0,0 +1,78 @@ +// A basic clang -cc1 command-line, and simple environment check. + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 2>&1 \ +// RUN: | FileCheck -check-prefix=CC1 %s +// CC1: clang{{.*}} "-cc1" "-triple" "msp430" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 \ +// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430 %s + +// MSP430: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" +// MSP430: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crt0.o" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtbegin.o" +// MSP430: "--start-group" "-lmul_none" "-lgcc" "-lc" "-lcrt" "-lnosys" "--end-group" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtend.o" +// MSP430: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crtn.o" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nodefaultlibs \ +// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-NO-DFT-LIB %s + +// MSP430-NO-DFT-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" +// MSP430-NO-DFT-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crt0.o" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtbegin.o" +// MSP430-NO-DFT-LIB: "--start-group" "-lmul_none" "-lgcc" "--end-group" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430/crtend.o" +// MSP430-NO-DFT-LIB: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430/crtn.o" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nostartfiles \ +// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-NO-START %s + +// MSP430-NO-START: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" +// MSP430-NO-START: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" +// MSP430-NO-START: "--start-group" "-lmul_none" "-lgcc" "-lc" "-lcrt" "-lnosys" "--end-group" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -nostdlib \ +// RUN: --gcc-toolchain=%S/Inputs/basic_msp430_tree 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-NO-STD-LIB %s + +// MSP430-NO-STD-LIB: "{{.*}}Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../bin/msp430-elf-ld" +// MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/430" +// MSP430-NO-STD-LIB: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/7.3.1/../../../../msp430-elf/lib/430" +// MSP430-NO-STD-LIB: "--start-group" "-lmul_none" "-lgcc" "--end-group" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f147 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-16BIT %s +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f147 -mhwmult=auto 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-16BIT %s +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mhwmult=16bit 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-16BIT %s + +// MSP430-HWMult-16BIT: "--start-group" "-lmul_16" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f4783 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-32BIT %s +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f4783 -mhwmult=auto 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-32BIT %s +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mhwmult=32bit 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-32BIT %s + +// MSP430-HWMult-32BIT: "--start-group" "-lmul_32" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mhwmult=f5series 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-F5 %s +// MSP430-HWMult-F5: "--start-group" "-lmul_f5" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mhwmult=none 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-NONE %s +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mhwmult=none -mmcu=msp430f4783 2>&1 \ +// RUN: | FileCheck -check-prefix=MSP430-HWMult-NONE %s + +// MSP430-HWMult-NONE: "--start-group" "-lmul_none" Index: cfe/trunk/test/Driver/no-integrated-as.c =================================================================== --- cfe/trunk/test/Driver/no-integrated-as.c +++ cfe/trunk/test/Driver/no-integrated-as.c @@ -9,11 +9,6 @@ // IAS-NOT: -no-integrated-as // RUN: %clang -target i386 -### -c %s 2>&1 | FileCheck %s -check-prefix DEFAULT +// RUN: %clang -target msp430 -### -c %s 2>&1 | FileCheck %s -check-prefix DEFAULT // DEFAULT-NOT: -no-integrated-as - -// RUN: %clang -target msp430 -### -c %s 2>&1 \ -// RUN: | FileCheck %s -check-prefix NO-IAS-DEFAULT - -// NO-IAS-DEFAULT: -no-integrated-as -