jozefl updated this revision to Diff 370350.
jozefl added a comment.

Rebased onto current upstream.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D109174/new/

https://reviews.llvm.org/D109174

Files:
  clang/include/clang/Basic/DiagnosticDriverKinds.td
  clang/lib/Basic/Targets/MSP430.cpp
  clang/lib/Basic/Targets/MSP430.h
  clang/lib/Driver/ToolChains/CommonArgs.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/MSP430.cpp
  clang/lib/Driver/ToolChains/MSP430.h
  clang/test/Driver/msp430-cpu.c
  clang/test/Driver/msp430-mmcu.c
  clang/test/Driver/msp430-toolchain.c
  clang/test/Misc/target-invalid-cpu-note.c
  clang/test/Preprocessor/msp430-defs.c
  llvm/lib/Target/MSP430/MSP430.td
  llvm/lib/Target/MSP430/MSP430Subtarget.cpp
  llvm/lib/Target/MSP430/MSP430Subtarget.h
  llvm/test/CodeGen/MSP430/build-attrs.ll

Index: llvm/test/CodeGen/MSP430/build-attrs.ll
===================================================================
--- llvm/test/CodeGen/MSP430/build-attrs.ll
+++ 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
Index: llvm/lib/Target/MSP430/MSP430Subtarget.h
===================================================================
--- llvm/lib/Target/MSP430/MSP430Subtarget.h
+++ 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;
   }
Index: llvm/lib/Target/MSP430/MSP430Subtarget.cpp
===================================================================
--- llvm/lib/Target/MSP430/MSP430Subtarget.cpp
+++ 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";
Index: llvm/lib/Target/MSP430/MSP430.td
===================================================================
--- llvm/lib/Target/MSP430/MSP430.td
+++ 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
Index: clang/test/Preprocessor/msp430-defs.c
===================================================================
--- /dev/null
+++ 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__
Index: clang/test/Misc/target-invalid-cpu-note.c
===================================================================
--- clang/test/Misc/target-invalid-cpu-note.c
+++ clang/test/Misc/target-invalid-cpu-note.c
@@ -205,3 +205,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: note: valid target CPU values are: generic-rv64, rocket-rv64, sifive-7-rv64, 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: note: valid target CPU values are: generic, msp430, msp430x, msp430xv2
Index: clang/test/Driver/msp430-toolchain.c
===================================================================
--- clang/test/Driver/msp430-toolchain.c
+++ 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
Index: clang/test/Driver/msp430-mmcu.c
===================================================================
--- clang/test/Driver/msp430-mmcu.c
+++ 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"
Index: clang/test/Driver/msp430-cpu.c
===================================================================
--- /dev/null
+++ 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
Index: clang/lib/Driver/ToolChains/MSP430.h
===================================================================
--- clang/lib/Driver/ToolChains/MSP430.h
+++ clang/lib/Driver/ToolChains/MSP430.h
@@ -78,6 +78,8 @@
 
 void getMSP430TargetFeatures(const Driver &D, const llvm::opt::ArgList &Args,
                              std::vector<llvm::StringRef> &Features);
+std::string getMSP430CPUFromMCU(StringRef MCU);
+
 } // end namespace msp430
 } // end namespace tools
 } // end namespace driver
Index: clang/lib/Driver/ToolChains/MSP430.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MSP430.cpp
+++ clang/lib/Driver/ToolChains/MSP430.cpp
@@ -115,14 +115,39 @@
     Features.push_back("+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) {
+  MCUData LoadedMCUData = loadMCUData(MCU);
+  return std::string(LoadedMCUData.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<StringRef> &Features) {
   const Arg *MCUArg = Args.getLastArg(options::OPT_mmcu_EQ);
   StringRef SupportedHWMult;
+
   if (MCUArg) {
     MCUData LoadedMCUData = loadMCUData(MCUArg->getValue());
     if (!LoadedMCUData.isValid()) {
@@ -130,6 +155,8 @@
       return;
     }
     SupportedHWMult = LoadedMCUData.HWMult;
+    if (const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ))
+      validateSelectedCPU(D, CPUArg->getValue(), LoadedMCUData.CPU);
   }
 
   processHWMultFeatures(D, Args, Features, SupportedHWMult);
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ 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(Args, TargetTriple);
+  bool msp430x = (CPUName == "msp430x" || CPUName == "msp430xv2");
+  addMultilibFlag(msp430x, "msp430x", Flags);
   if (Result.Multilibs.select(Flags, Result.SelectedMultilib))
     return true;
 
Index: clang/lib/Driver/ToolChains/CommonArgs.cpp
===================================================================
--- clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ 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"
@@ -395,6 +396,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))
Index: clang/lib/Basic/Targets/MSP430.h
===================================================================
--- clang/lib/Basic/Targets/MSP430.h
+++ 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,19 @@
 
   bool allowsLargerPreferedTypeAlignment() const override { return false; }
 
+  bool hasMSP430X() const {
+    return llvm::StringSwitch<bool>(CPU)
+        .Case("msp430x", true)
+        .Case("msp430xv2", true)
+        .Default(false);
+  }
+
+  // Currently unused for checking MSP430-specific features.
   bool hasFeature(StringRef Feature) const override {
-    return Feature == "msp430";
+    assert(Feature != "msp430" && Feature != "msp430x" &&
+           Feature != "hwmult16" && Feature != "hwmult32" &&
+           Feature != "hwmultf5" && "unexpected check of MSP430 feature");
+    return false;
   }
 
   ArrayRef<const char *> getGCCRegNames() const override;
@@ -96,6 +109,29 @@
     // FIXME: implement
     return TargetInfo::CharPtrBuiltinVaList;
   }
+
+  bool
+  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,
+                 StringRef CPU,
+                 const std::vector<std::string> &FeaturesVec) const override {
+    Features["msp430x"] = hasMSP430X();
+    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<StringRef> &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
Index: clang/lib/Basic/Targets/MSP430.cpp
===================================================================
--- clang/lib/Basic/Targets/MSP430.cpp
+++ 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<const char *> 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 (hasMSP430X())
+    Builder.defineMacro("__MSP430X__");
 }
Index: clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -553,15 +553,18 @@
 
 def warn_drv_msp430_hwmult_unsupported : Warning<
   "the given MCU does not support hardware multiply, but '-mhwmult' is set to "
-  "%0">, InGroup<InvalidCommandLineArgument>;
+  "'%0'">, InGroup<InvalidCommandLineArgument>;
 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<InvalidCommandLineArgument>;
 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<InvalidCommandLineArgument>;
+def warn_drv_msp430_cpu_mismatch : Warning<
+  "the given MCU supports the '%0' CPU, but '-mcpu' is set to '%1'">,
+   InGroup<InvalidCommandLineArgument>;
 
 def warn_drv_libstdcxx_not_found : Warning<
   "include path for libstdc++ headers not found; pass '-stdlib=libc++' on the "
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to