diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index bc97411..07f0a65 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -71,7 +71,6 @@ arc_handle_option (struct gcc_options *opts,
   int value = decoded->value;
   const char *arg = decoded->arg;
   static int mcpu_seen = PROCESSOR_NONE;
-  char *p;
 
   switch (code)
     {
@@ -85,45 +84,8 @@ arc_handle_option (struct gcc_options *opts,
       break;
 
     case OPT_mmpy_option_:
-      p = ASTRDUP (arg);
-
-      if (!strcmp (p, "0")
-	  || !strcmp (p, "none"))
-	opts->x_arc_mpy_option = 0;
-      else if (!strcmp (p, "1")
-	  || !strcmp (p, "w"))
-	{
-	  opts->x_arc_mpy_option = 1;
-	  warning_at (loc, 0, "Unsupported value for mmpy-option");
-	}
-      else if (!strcmp (p, "2")
-	       || !strcmp (p, "mpy")
-	       || !strcmp (p, "wlh1"))
-	opts->x_arc_mpy_option = 2;
-      else if (!strcmp (p, "3")
-	       || !strcmp (p, "wlh2"))
-	opts->x_arc_mpy_option = 3;
-      else if (!strcmp (p, "4")
-	       || !strcmp (p, "wlh3"))
-	opts->x_arc_mpy_option = 4;
-      else if (!strcmp (p, "5")
-	       || !strcmp (p, "wlh4"))
-	opts->x_arc_mpy_option = 5;
-      else if (!strcmp (p, "6")
-	       || !strcmp (p, "wlh5"))
-	opts->x_arc_mpy_option = 6;
-      else if (!strcmp (p, "7")
-	       || !strcmp (p, "plus_dmpy"))
-	opts->x_arc_mpy_option = 7;
-      else if (!strcmp (p, "8")
-	       || !strcmp (p, "plus_macd"))
-	opts->x_arc_mpy_option = 8;
-      else if (!strcmp (p, "9")
-	       || !strcmp (p, "plus_qmacw"))
-	opts->x_arc_mpy_option = 9;
-      else
-	error_at (loc, "unknown value %qs for -mmpy-option", arg);
-
+      if (opts->x_arc_mpy_option == 1)
+	warning_at (loc, 0, "Unsupported value for mmpy-option");
       break;
 
     default:
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 20a526b..5685100 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -53,13 +53,76 @@ mARC700
 Target Report
 Same as -mA7.
 
-TargetVariable
-int arc_mpy_option = DEFAULT_arc_mpy_option
-
 mmpy-option=
-Target RejectNegative Joined
+Target RejectNegative Joined Enum(arc_mpy) Var(arc_mpy_option) Init(DEFAULT_arc_mpy_option)
 -mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
 
+Enum
+Name(arc_mpy) Type(int)
+
+EnumValue
+Enum(arc_mpy) String(0) Value(0)
+
+EnumValue
+Enum(arc_mpy) String(none) Value(0) Canonical
+
+EnumValue
+Enum(arc_mpy) String(1) Value(1)
+
+EnumValue
+Enum(arc_mpy) String(w) Value(1) Canonical
+
+EnumValue
+Enum(arc_mpy) String(2) Value(2)
+
+EnumValue
+Enum(arc_mpy) String(mpy) Value(2)
+
+EnumValue
+Enum(arc_mpy) String(wlh1) Value(2) Canonical
+
+EnumValue
+Enum(arc_mpy) String(3) Value(3)
+
+EnumValue
+Enum(arc_mpy) String(wlh2) Value(3) Canonical
+
+EnumValue
+Enum(arc_mpy) String(4) Value(4)
+
+EnumValue
+Enum(arc_mpy) String(wlh3) Value(4) Canonical
+
+EnumValue
+Enum(arc_mpy) String(5) Value(5)
+
+EnumValue
+Enum(arc_mpy) String(wlh4) Value(5) Canonical
+
+EnumValue
+Enum(arc_mpy) String(6) Value(6)
+
+EnumValue
+Enum(arc_mpy) String(wlh5) Value(6) Canonical
+
+EnumValue
+Enum(arc_mpy) String(7) Value(7)
+
+EnumValue
+Enum(arc_mpy) String(plus_dmpy) Value(7) Canonical
+
+EnumValue
+Enum(arc_mpy) String(8) Value(8)
+
+EnumValue
+Enum(arc_mpy) String(plus_macd) Value(8) Canonical
+
+EnumValue
+Enum(arc_mpy) String(9) Value(9)
+
+EnumValue
+Enum(arc_mpy) String(plus_qmacw) Value(9) Canonical
+
 mdiv-rem
 Target Report Mask(DIVREM)
 Enable DIV-REM instructions for ARCv2.
-- 
2.6.4

--- Patch #2: New test for nps400 .cpu flag

diff --git a/gcc/testsuite/gcc.target/arc/nps400-cpu-flag.c b/gcc/testsuite/gcc.target/arc/nps400-cpu-flag.c
new file mode 100644
index 0000000..fe80ce5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/nps400-cpu-flag.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400" } */
+
+/* { dg-final { scan-assembler ".cpu NPS400" } } */
-- 
2.6.4

--- Patch #3: Track specific processor type

diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
index 7994543..bfd3f23 100644
--- a/gcc/config/arc/arc-arch.h
+++ b/gcc/config/arc/arc-arch.h
@@ -68,6 +68,9 @@ typedef struct
   /* Architecture class.  */
   enum base_architecture arch;
 
+  /* Specific processor type.  */
+  enum processor_type processor;
+
   /* Specific flags.  */
   const unsigned long long flags;
 
@@ -108,12 +111,12 @@ const arc_arch_t arc_arch_types[] =
 
 const arc_cpu_t arc_cpu_types[] =
   {
-    {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE},
+    {"none", BASE_ARCH_NONE, PROCESSOR_NONE, 0, ARC_TUNE_NONE},
 #define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
-    {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE},
+    {#NAME, BASE_ARCH_##ARCH, PROCESSOR_##NAME, FLAGS, ARC_TUNE_##TUNE},
 #include "arc-cpus.def"
 #undef ARC_CPU
-    {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE}
+    {NULL, BASE_ARCH_END, PROCESSOR_NONE, 0, ARC_TUNE_NONE}
   };
 
 #endif
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index c075bcb..3bce7ef 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -800,7 +800,10 @@ arc_override_options (void)
       arc_cpu_string = "HS";
       break;
     case BASE_ARCH_700:
-      arc_cpu_string = "ARC700";
+      if (arc_selected_cpu->processor == PROCESSOR_nps400)
+	arc_cpu_string = "NPS400";
+      else
+	arc_cpu_string = "ARC700";
       break;
     case BASE_ARCH_6xx:
       arc_cpu_string = "ARC600";
diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
index 6117968..0c24cda 100644
--- a/gcc/config/arc/driver-arc.c
+++ b/gcc/config/arc/driver-arc.c
@@ -64,7 +64,10 @@ arc_cpu_to_as (int argc, const char **argv)
     case BASE_ARCH_hs:
       return "-mcpu=archs";
     case BASE_ARCH_700:
-      return "-mcpu=arc700 -mEA";
+      if (arc_selected_cpu->processor == PROCESSOR_nps400)
+	return "-mcpu=nps400 -mEA";
+      else
+	return "-mcpu=arc700 -mEA";
     case BASE_ARCH_6xx:
       if (arc_selected_cpu->flags & FL_MUL64)
 	return "-mcpu=arc600 -mmul64 -mnorm";
