diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -556,15 +556,18 @@ def warn_drv_msp430_hwmult_unsupported : Warning< "the given MCU does not support hardware multiply, but '-mhwmult' is set to " - "%0">, InGroup; + "'%0'">, InGroup; def warn_drv_msp430_hwmult_mismatch : Warning< - "the given MCU supports %0 hardware multiply, but '-mhwmult' is set to %1">, + "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 an MSP430 device, or '-mhwmult' " "to set the hardware multiply type explicitly">, InGroup; +def warn_drv_msp430_cpu_mismatch : Warning< + "the given MCU supports the '%0' CPU, but '-mcpu' is set to '%1'">, + InGroup; def warn_drv_libstdcxx_not_found : Warning< "include path for libstdc++ headers not found; pass '-stdlib=libc++' on the " diff --git a/clang/lib/Basic/Targets/MSP430.h b/clang/lib/Basic/Targets/MSP430.h --- a/clang/lib/Basic/Targets/MSP430.h +++ b/clang/lib/Basic/Targets/MSP430.h @@ -23,6 +23,8 @@ class LLVM_LIBRARY_VISIBILITY MSP430TargetInfo : public TargetInfo { static const char *const GCCRegNames[]; + static const llvm::StringLiteral ValidCPUNames[4]; + std::string CPU; public: MSP430TargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -57,8 +59,21 @@ bool allowsLargerPreferedTypeAlignment() const override { return false; } + /// Check for support of feature \p Feature. + /// + /// Currently only the driver needs to know about hwmult features, so checking + /// their availability here is not required. bool hasFeature(StringRef Feature) const override { - return Feature == "msp430"; + assert(Feature != "hwmult16" && Feature != "hwmult32" && + Feature != "hwmultf5" && "unexpected check of hwmult feature"); + if (Feature == "msp430") + return true; + if (Feature == "msp430x") + return llvm::StringSwitch(CPU) + .Case("msp430x", true) + .Case("msp430xv2", true) + .Default(false); + return false; } ArrayRef getGCCRegNames() const override; @@ -96,6 +111,29 @@ // FIXME: implement return TargetInfo::CharPtrBuiltinVaList; } + + bool + initFeatureMap(llvm::StringMap &Features, DiagnosticsEngine &Diags, + StringRef CPU, + const std::vector &FeaturesVec) const override { + Features["msp430x"] = hasFeature("msp430x"); + return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); + } + + bool setCPU(const std::string &Name) override { + if (!isValidCPUName(Name)) + return false; + CPU = Name; + return true; + } + + void fillValidCPUList(SmallVectorImpl &Values) const override { + Values.append(std::begin(ValidCPUNames), std::end(ValidCPUNames)); + } + + bool isValidCPUName(StringRef Name) const override { + return llvm::find(ValidCPUNames, Name) != std::end(ValidCPUNames); + } }; } // namespace targets diff --git a/clang/lib/Basic/Targets/MSP430.cpp b/clang/lib/Basic/Targets/MSP430.cpp --- a/clang/lib/Basic/Targets/MSP430.cpp +++ b/clang/lib/Basic/Targets/MSP430.cpp @@ -21,6 +21,9 @@ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15" }; +constexpr llvm::StringLiteral MSP430TargetInfo::ValidCPUNames[4] = { + {"generic"}, {"msp430"}, {"msp430x"}, {"msp430xv2"}}; + ArrayRef MSP430TargetInfo::getGCCRegNames() const { return llvm::makeArrayRef(GCCRegNames); } @@ -31,4 +34,6 @@ Builder.defineMacro("__MSP430__"); Builder.defineMacro("__ELF__"); // FIXME: defines for different 'flavours' of MCU + if (hasFeature("msp430x")) + Builder.defineMacro("__MSP430X__"); } diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -17,6 +17,7 @@ #include "Arch/X86.h" #include "HIP.h" #include "Hexagon.h" +#include "MSP430.h" #include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/ObjCRuntime.h" @@ -396,6 +397,13 @@ return std::string(CPUName); } + case llvm::Triple::msp430: + if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ)) + return A->getValue(); + if (const Arg *A = Args.getLastArg(options::OPT_mmcu_EQ)) + return msp430::getMSP430CPUFromMCU(A->getValue()); + return "msp430"; + case llvm::Triple::nvptx: case llvm::Triple::nvptx64: if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -1564,21 +1564,33 @@ StringRef Path, const ArgList &Args, DetectedMultilibs &Result) { FilterNonExistent NonExistent(Path, "/crtbegin.o", D.getVFS()); - Multilib WithoutExceptions = makeMultilib("/430").flag("-exceptions"); - Multilib WithExceptions = makeMultilib("/430/exceptions").flag("+exceptions"); - - // FIXME: when clang starts to support msp430x ISA additional logic - // to select between multilib must be implemented + Multilib WithoutExceptions = + makeMultilib("/430").flag("-exceptions").flag("-msp430x"); + Multilib WithExceptions = + makeMultilib("/430/exceptions").flag("+exceptions").flag("-msp430x"); + Multilib WithoutExceptions430x = + makeMultilib("").flag("-exceptions").flag("+msp430x"); + Multilib WithExceptions430x = + makeMultilib("/exceptions").flag("+exceptions").flag("+msp430x"); + + // FIXME: When LLVM starts to support the msp430x large memory model (20-bit + // pointers) additional logic to select between multilibs must be implemented. // Multilib MSP430xMultilib = makeMultilib("/large"); Result.Multilibs.push_back(WithoutExceptions); Result.Multilibs.push_back(WithExceptions); + Result.Multilibs.push_back(WithoutExceptions430x); + Result.Multilibs.push_back(WithExceptions430x); Result.Multilibs.FilterOut(NonExistent); Multilib::flags_list Flags; addMultilibFlag(Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, false), "exceptions", Flags); + + std::string CPUName = tools::getCPUName(D, Args, TargetTriple); + bool msp430x = (CPUName == "msp430x" || CPUName == "msp430xv2"); + addMultilibFlag(msp430x, "msp430x", Flags); if (Result.Multilibs.select(Flags, Result.SelectedMultilib)) return true; diff --git a/clang/lib/Driver/ToolChains/MSP430.h b/clang/lib/Driver/ToolChains/MSP430.h --- a/clang/lib/Driver/ToolChains/MSP430.h +++ b/clang/lib/Driver/ToolChains/MSP430.h @@ -78,6 +78,8 @@ void getMSP430TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args, std::vector &Features); +std::string getMSP430CPUFromMCU(StringRef MCU); + } // end namespace msp430 } // end namespace tools } // end namespace driver diff --git a/clang/lib/Driver/ToolChains/MSP430.cpp b/clang/lib/Driver/ToolChains/MSP430.cpp --- a/clang/lib/Driver/ToolChains/MSP430.cpp +++ b/clang/lib/Driver/ToolChains/MSP430.cpp @@ -117,14 +117,38 @@ .Case("f5series", "+hwmultf5")); } -/// Process the -mmcu= and -mhwmult= options to determine the target features. +/// Emit a warning if the \p SelectedCPU value passed to -mcpu= does not match +/// the \p SupportedCPU extracted from the MCU data for the MCU selected with +/// -mmcu=. /// -/// This is the only time Clang will warn about conflicts between these options, -/// or issues with the values passed to them. +/// Clang's generic option processing handles invalid values passed to -mcpu=. +static void validateSelectedCPU(const Driver &D, StringRef SelectedCPU, + StringRef SupportedCPU) { + if (SelectedCPU == "generic") + SelectedCPU = "msp430"; + if (SelectedCPU != SupportedCPU) + D.Diag(clang::diag::warn_drv_msp430_cpu_mismatch) + << SupportedCPU << SelectedCPU; +} + +/// Return the supported CPU for the given MCU. +/// +/// If the MCU is not valid, Clang has already emitted a warning, so just return +/// the default "msp430" CPU. +std::string msp430::getMSP430CPUFromMCU(StringRef MCU) { + return std::string(getMCUData(MCU).CPU); +} + +/// Process the -mmcu=, -mcpu= and -mhwmult= options to determine the target +/// features. +/// +/// Emit warnings if the selected MCU does not support the selected CPU or +/// hardware multiply version. void msp430::getMSP430TargetFeatures(const Driver &D, const ArgList &Args, std::vector &Features) { const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ); StringRef SupportedHWMult; + if (MCUArg) { MCUData LoadedMCUData = getMCUData(MCUArg->getValue()); if (!LoadedMCUData.isValid()) { @@ -132,6 +156,8 @@ return; } SupportedHWMult = LoadedMCUData.HWMult; + if (const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ)) + validateSelectedCPU(D, CPUArg->getValue(), LoadedMCUData.CPU); } addHWMultFeature(D, Args, SupportedHWMult, Features); diff --git a/clang/test/Driver/msp430-cpu.c b/clang/test/Driver/msp430-cpu.c new file mode 100644 --- /dev/null +++ b/clang/test/Driver/msp430-cpu.c @@ -0,0 +1,19 @@ +// Check the correct translation of -mcpu= to -target-cpu. + +// RUN: %clang -target msp430 -mcpu=generic -### -c %s 2>&1 | FileCheck -check-prefix=GENERIC %s +// GENERIC: "-cc1"{{.*}} "-target-cpu" "generic" + +// RUN: %clang -target msp430 -### -c %s 2>&1 | FileCheck -check-prefix=MSP430 %s +// RUN: %clang -target msp430 -mcpu=msp430 -### -c %s 2>&1 | FileCheck -check-prefix=MSP430 %s +// MSP430: "-cc1"{{.*}} "-target-cpu" "msp430" + +// RUN: %clang -target msp430 -mcpu=msp430x -### -c %s 2>&1 | FileCheck -check-prefix=MSP430X %s +// MSP430X: "-cc1"{{.*}} "-target-cpu" "msp430x" + +// RUN: %clang -target msp430 -mcpu=msp430xv2 -### -c %s 2>&1 | FileCheck -check-prefix=MSP430XV2 %s +// MSP430XV2: "-cc1"{{.*}} "-target-cpu" "msp430xv2" + +// Test that Clang emits an error on an invalid value passed to -mcpu=. +// RUN: not %clang -target msp430 -mcpu=msp430xv3 -v -c %s 2>&1 | FileCheck -check-prefix=MSP430XV3 %s +// MSP430XV3: error: unknown target CPU 'msp430xv3' +// MSP430XV3-NEXT: note: valid target CPU values are: generic, msp430, msp430x, msp430xv2 diff --git a/clang/test/Driver/msp430-mmcu.c b/clang/test/Driver/msp430-mmcu.c --- a/clang/test/Driver/msp430-mmcu.c +++ b/clang/test/Driver/msp430-mmcu.c @@ -25,6 +25,7 @@ // RUN: | FileCheck -check-prefix=MSP430-C111 %s // MSP430-C111: clang{{.*}} "-cc1" {{.*}} "-D__MSP430C111__" +// MSP430-C111: "-target-cpu" "msp430" // MSP430-C111-NOT: "-target-feature" "+hwmult16" // MSP430-C111-NOT: "-target-feature" "+hwmult32" // MSP430-C111-NOT: "-target-feature" "+hwmultf5" @@ -34,6 +35,7 @@ // RUN: | FileCheck -check-prefix=MSP430-I2020 %s // MSP430-I2020: clang{{.*}} "-cc1" {{.*}} "-D__MSP430i2020__" +// MSP430-I2020: "-target-cpu" "msp430" // MSP430-I2020: "-target-feature" "+hwmult16" // MSP430-I2020: msp430-elf-ld{{.*}} "-Tmsp430i2020.ld" @@ -41,6 +43,7 @@ // RUN: | FileCheck -check-prefix=MSP430-F47126 %s // MSP430-F47126: clang{{.*}} "-cc1" {{.*}} "-D__MSP430F47126__" +// MSP430-F47126: "-target-cpu" "msp430x" // MSP430-F47126: "-target-feature" "+hwmult32" // MSP430-F47126: msp430-elf-ld{{.*}} "-Tmsp430f47126.ld" @@ -48,6 +51,7 @@ // RAN: | FileCheck -check-prefix=MSP430-FR5969 %s // MSP430-FR5969: clang{{.*}} "-cc1" {{.*}} "-D__MSP430FR5969__" +// MSP430-FR5969: "-target-cpu" "msp430xv2" // MSP430-FR5969: "-target-feature" "+hwmultf5" // MSP430-FR5969: msp430-elf-ld{{.*}} "-Tmsp430fr5969.ld" @@ -67,3 +71,43 @@ // RUN: | FileCheck -check-prefix=MSP430 %s // MSP430: error: the clang compiler does not support 'msp430' + +// Test that the CPU derived from -mmcu= can be overriden with -mcpu=, but that a +// warning will be emitted. + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430fr5969 \ +// RUN: -mcpu=msp430x 2>&1 | FileCheck -check-prefix=MSP430-FR5969-430X %s + +// MSP430-FR5969-430X: warning: the given MCU supports the 'msp430xv2' CPU, but '-mcpu' is set to 'msp430x' +// MSP430-FR5969-430X: clang{{.*}} "-cc1" {{.*}} "-D__MSP430FR5969__" +// MSP430-FR5969-430X: "-target-cpu" "msp430x" +// MSP430-FR5969-430X: "-target-feature" "+hwmultf5" +// MSP430-FR5969-430X: msp430-elf-ld{{.*}} "-Tmsp430fr5969.ld" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430fr5969 \ +// RUN: -mcpu=msp430 2>&1 | FileCheck -check-prefix=MSP430-FR5969-430 %s + +// MSP430-FR5969-430: warning: the given MCU supports the 'msp430xv2' CPU, but '-mcpu' is set to 'msp430' +// MSP430-FR5969-430: clang{{.*}} "-cc1" {{.*}} "-D__MSP430FR5969__" +// MSP430-FR5969-430: "-target-cpu" "msp430" +// MSP430-FR5969-430: "-target-feature" "+hwmultf5" +// MSP430-FR5969-430: msp430-elf-ld{{.*}} "-Tmsp430fr5969.ld" + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430c111 \ +// RUN: -mcpu=msp430x 2>&1 | FileCheck -check-prefix=MSP430-C111-430X %s + +// MSP430-C111-430X: warning: the given MCU supports the 'msp430' CPU, but '-mcpu' is set to 'msp430x' +// MSP430-C111-430X: clang{{.*}} "-cc1" {{.*}} "-D__MSP430C111__" +// MSP430-C111-430X: "-target-cpu" "msp430x" +// MSP430-C111-430X: msp430-elf-ld{{.*}} "-Tmsp430c111.ld" + +// Test that the CPU name "generic" implies the "msp430" CPU when checking for +// CPU compatibility. +// +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430c111 \ +// RUN: -mcpu=generic 2>&1 | FileCheck -check-prefix=MSP430-C111-GENERIC %s + +// MSP430-C111-GENERIC-NOT: warning: +// MSP430-C111-GENERIC: clang{{.*}} "-cc1" {{.*}} "-D__MSP430C111__" +// MSP430-C111-GENERIC: "-target-cpu" "generic" +// MSP430-C111-GENERIC: msp430-elf-ld{{.*}} "-Tmsp430c111.ld" diff --git a/clang/test/Driver/msp430-toolchain.c b/clang/test/Driver/msp430-toolchain.c --- a/clang/test/Driver/msp430-toolchain.c +++ b/clang/test/Driver/msp430-toolchain.c @@ -64,8 +64,6 @@ // MISC-FLAGS-2-NEG-NOT: "-z" // MISC-FLAGS-2-NEG-NOT: "--relax" -// Tests for -nostdlib, -nostartfiles, -nodefaultfiles and -f(no-)exceptions - // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -rtlib=libgcc \ // RUN: --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1 // RUN: FileCheck -check-prefix=LIBS-DEFAULT-POS %s < %t @@ -112,6 +110,7 @@ // LIBS-COMPILER-RT-NEG-NOT: crtend.o // LIBS-COMPILER-RT-NEG-NOT: /exceptions +// Tests for -mcpu=msp430x(v2) and -f(no-)exceptions. // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -rtlib=libgcc -fexceptions \ // RUN: --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1 // RUN: FileCheck -check-prefix=LIBS-EXC-POS %s < %t @@ -126,6 +125,44 @@ // LIBS-EXC-NEG-NOT: "{{.*}}/430" // LIBS-EXC-NEG-NOT: "{{.*}}430/crt{{.*}}" +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -rtlib=libgcc -mcpu=msp430x \ +// RUN: --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1 +// RUN: FileCheck -check-prefix=LIBS-430X-POS %s < %t +// RUN: FileCheck -check-prefix=LIBS-430X-NEG %s < %t +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -rtlib=libgcc -mcpu=msp430xv2 \ +// RUN: --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1 +// RUN: FileCheck -check-prefix=LIBS-430X-POS %s < %t +// RUN: FileCheck -check-prefix=LIBS-430X-NEG %s < %t +// LIBS-430X-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" +// LIBS-430X-POS: "{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib{{/|\\\\}}crt0.o" +// LIBS-430X-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1{{/|\\\\}}crtbegin_no_eh.o" +// LIBS-430X-POS: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1{{/|\\\\}}" +// LIBS-430X-POS: "-L{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib{{/|\\\\}}" +// LIBS-430X-POS: "-lgcc" "--start-group" "-lmul_none" "-lc" "-lgcc" "-lcrt" "-lnosys" "--end-group" +// LIBS-430X-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1{{/|\\\\}}crtend_no_eh.o" "-lgcc" +// LIBS-430X-NEG-NOT: "{{.*}}/430" +// LIBS-430X-NEG-NOT: "{{.*}}430/crt{{.*}}" +// LIBS-430X-NEG-NOT: /exceptions + +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -rtlib=libgcc -mcpu=msp430x -fexceptions \ +// RUN: --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1 +// RUN: FileCheck -check-prefix=LIBS-430X-EXC-POS %s < %t +// RUN: FileCheck -check-prefix=LIBS-430X-EXC-NEG %s < %t +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -rtlib=libgcc -mcpu=msp430xv2 -fexceptions \ +// RUN: --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1 +// RUN: FileCheck -check-prefix=LIBS-430X-EXC-POS %s < %t +// RUN: FileCheck -check-prefix=LIBS-430X-EXC-NEG %s < %t +// LIBS-430X-EXC-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" +// LIBS-430X-EXC-POS: "{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib/exceptions{{/|\\\\}}crt0.o" +// LIBS-430X-EXC-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/exceptions{{/|\\\\}}crtbegin.o" +// LIBS-430X-EXC-POS: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/exceptions" +// LIBS-430X-EXC-POS: "-L{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib/exceptions" +// LIBS-430X-EXC-POS: "-lgcc" "--start-group" "-lmul_none" "-lc" "-lgcc" "-lcrt" "-lnosys" "--end-group" +// LIBS-430X-EXC-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/exceptions{{/|\\\\}}crtend.o" "-lgcc" +// LIBS-430X-EXC-NEG-NOT: "{{.*}}/430" +// LIBS-430X-EXC-NEG-NOT: "{{.*}}430/crt{{.*}}" + +// Tests for -fstack-protector, -nostdlib, -nostartfiles and -nodefaultlibs. // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -rtlib=libgcc \ // RUN: -fstack-protector --sysroot="%S/Inputs/basic_msp430_tree" 2>&1 \ // RUN: | FileCheck -check-prefix=LIBS-SSP %s @@ -266,3 +303,30 @@ // RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mhwmult=none -mmcu=msp430f4783 --sysroot="" 2>&1 \ // RUN: | FileCheck -check-prefix=HWMult-NONE %s // HWMult-NONE: "--start-group" "-lmul_none" + +// Test for the correct multilib selection when overriding the CPU of an MCU. +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f5529 -mcpu=msp430 \ +// RUN: -rtlib=libgcc --sysroot="%S/Inputs/basic_msp430_tree" > %t 2>&1 +// RUN: FileCheck -check-prefix=LIBS-OVERRIDE-430-POS %s < %t +// RUN: FileCheck -check-prefix=LIBS-OVERRIDE-430-NEG %s < %t +// RUN: %clang %s -### -no-canonical-prefixes -target msp430 -mmcu=msp430f5529 -mcpu=msp430 \ +// RUN: -rtlib=libgcc --gcc-toolchain="%S/Inputs/basic_msp430_tree" --sysroot="" 2>&1 \ +// RUN: | FileCheck -check-prefix=LIBS-OVERRIDE-430-GCC-TOOLCHAIN %s +// LIBS-OVERRIDE-430-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" +// LIBS-OVERRIDE-430-POS: "{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crt0.o" +// LIBS-OVERRIDE-430-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430{{/|\\\\}}crtbegin_no_eh.o" +// LIBS-OVERRIDE-430-POS: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430" +// LIBS-OVERRIDE-430-POS: "-L{{.*}}/Inputs/basic_msp430_tree{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430" +// LIBS-OVERRIDE-430-POS: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430{{/|\\\\}}crtend_no_eh.o" "-lgcc" +// LIBS-OVERRIDE-430-GCC-TOOLCHAIN: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/../../..{{/|\\\\}}..{{/|\\\\}}bin{{/|\\\\}}msp430-elf-ld" +// LIBS-OVERRIDE-430-GCC-TOOLCHAIN: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430{{/|\\\\}}crt0.o" +// LIBS-OVERRIDE-430-GCC-TOOLCHAIN: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430{{/|\\\\}}crtbegin_no_eh.o" +// LIBS-OVERRIDE-430-GCC-TOOLCHAIN: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430" +// LIBS-OVERRIDE-430-GCC-TOOLCHAIN: "-L{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/../../..{{/|\\\\}}..{{/|\\\\}}msp430-elf{{/|\\\\}}lib/430" +// LIBS-OVERRIDE-430-GCC-TOOLCHAIN: "{{.*}}/Inputs/basic_msp430_tree/lib/gcc/msp430-elf/8.3.1/430{{/|\\\\}}crtend_no_eh.o" "-lgcc" +// LIBS-OVERRIDE-430-NEG-NOT: crtbegin.o +// LIBS-OVERRIDE-430-NEG-NOT: -lssp_nonshared +// LIBS-OVERRIDE-430-NEG-NOT: -lssp +// LIBS-OVERRIDE-430-NEG-NOT: clang_rt +// LIBS-OVERRIDE-430-NEG-NOT: crtend.o +// LIBS-OVERRIDE-430-NEG-NOT: /exceptions diff --git a/clang/test/Misc/target-invalid-cpu-note.c b/clang/test/Misc/target-invalid-cpu-note.c --- a/clang/test/Misc/target-invalid-cpu-note.c +++ b/clang/test/Misc/target-invalid-cpu-note.c @@ -94,3 +94,7 @@ // RUN: not %clang_cc1 -triple riscv64 -tune-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix TUNE-RISCV64 // TUNE-RISCV64: error: unknown target CPU 'not-a-cpu' // TUNE-RISCV64-NEXT: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-7-rv64, sifive-s21, sifive-s51, sifive-s54, sifive-s76, sifive-u54, sifive-u74, generic, rocket, sifive-7-series{{$}} + +// RUN: not %clang_cc1 -triple msp430 -target-cpu not-a-cpu -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix MSP430 +// MSP430: error: unknown target CPU 'not-a-cpu' +// MSP430-NEXT: note: valid target CPU values are: generic, msp430, msp430x, msp430xv2{{$}} diff --git a/clang/test/Preprocessor/msp430-defs.c b/clang/test/Preprocessor/msp430-defs.c new file mode 100644 --- /dev/null +++ b/clang/test/Preprocessor/msp430-defs.c @@ -0,0 +1,20 @@ +// Check the correct macros are defined for each CPU. + +// RUN: %clang -target msp430 -x c -E -dM %s -o - | FileCheck %s +// RUN: %clang -target msp430 -mcpu=generic -x c -E -dM %s -o - | FileCheck %s +// RUN: %clang -target msp430 -mcpu=msp430 -x c -E -dM %s -o - | FileCheck %s + +// CHECK: MSP430 +// CHECK: __ELF__ +// CHECK-NOT: __MSP430X__ +// CHECK: __MSP430__ + +// RUN: %clang -target msp430 -mcpu=msp430x -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=MSP430X %s +// RUN: %clang -target msp430 -mcpu=msp430xv2 -x c -E -dM %s -o - \ +// RUN: | FileCheck --check-prefix=MSP430X %s + +// MSP430X: MSP430 +// MSP430X: __ELF__ +// MSP430X: __MSP430X__ +// MSP430X: __MSP430__ diff --git a/llvm/lib/Target/MSP430/MSP430.td b/llvm/lib/Target/MSP430/MSP430.td --- a/llvm/lib/Target/MSP430/MSP430.td +++ b/llvm/lib/Target/MSP430/MSP430.td @@ -18,8 +18,8 @@ // Subtarget Features. //===----------------------------------------------------------------------===// def FeatureX - : SubtargetFeature<"ext", "ExtendedInsts", "true", - "Enable MSP430-X extensions">; + : SubtargetFeature<"msp430x", "MSP430X", "true", + "Enable MSP430X extensions">; def FeatureHWMult16 : SubtargetFeature<"hwmult16", "HWMultMode", "HWMult16", @@ -42,6 +42,7 @@ def : Proc<"generic", []>; def : Proc<"msp430", []>; def : Proc<"msp430x", [FeatureX]>; +def : Proc<"msp430xv2", [FeatureX]>; //===----------------------------------------------------------------------===// // Register File Description diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.h b/llvm/lib/Target/MSP430/MSP430Subtarget.h --- a/llvm/lib/Target/MSP430/MSP430Subtarget.h +++ b/llvm/lib/Target/MSP430/MSP430Subtarget.h @@ -36,7 +36,7 @@ private: virtual void anchor(); - bool ExtendedInsts = false; + bool MSP430X = false; HWMultEnum HWMultMode = NoHWMult; MSP430FrameLowering FrameLowering; MSP430InstrInfo InstrInfo; @@ -60,6 +60,8 @@ bool hasHWMult32() const { return HWMultMode == HWMult32; } bool hasHWMultF5() const { return HWMultMode == HWMultF5; } + bool hasMSP430X() const { return MSP430X; } + const TargetFrameLowering *getFrameLowering() const override { return &FrameLowering; } diff --git a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp --- a/llvm/lib/Target/MSP430/MSP430Subtarget.cpp +++ b/llvm/lib/Target/MSP430/MSP430Subtarget.cpp @@ -40,9 +40,6 @@ MSP430Subtarget & MSP430Subtarget::initializeSubtargetDependencies(StringRef CPU, StringRef FS) { - ExtendedInsts = false; - HWMultMode = NoHWMult; - StringRef CPUName = CPU; if (CPUName.empty()) CPUName = "msp430"; diff --git a/llvm/test/CodeGen/MSP430/build-attrs.ll b/llvm/test/CodeGen/MSP430/build-attrs.ll --- a/llvm/test/CodeGen/MSP430/build-attrs.ll +++ b/llvm/test/CodeGen/MSP430/build-attrs.ll @@ -8,6 +8,8 @@ ; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430,SMALL ; RUN: llc -mtriple=msp430 -mcpu=msp430x -filetype=obj < %s \ ; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430X,SMALL +; RUN: llc -mtriple=msp430 -mcpu=msp430xv2 -filetype=obj < %s \ +; RUN: | llvm-readelf -A - | FileCheck %s --check-prefixes COMMON,MSP430X,SMALL ; COMMON: BuildAttributes { ; COMMON: FormatVersion: 0x41