public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/2] [ARC] Refurbish backend options
@ 2016-05-30 14:07 Claudiu Zissulescu
  2016-05-30 14:19 ` [PATCH 1/2] [ARC] New option handling, refurbish multilib support Claudiu Zissulescu
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-05-30 14:07 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, gnu, Francois.Bedard

This series of patches redefines the way how we handle the options
within the ARC backend. Firstly, a number of options got deprecated as
they were directed to control the assembler behavior, assembler which
got overhaul and ignores the options in question. Secondly, we remove
the capitalized cpu names accepted by mcpu option. Finally, we
introduced new cpu options, based on the Synopsys predefined CPU
templates to make easier the translation from hardware CPU template to
gcc options. Those new cpu options are handled by a number of scripts
which seamlessly generates gcc options, multilib variants, and
checking the allowed hardware extensions against gcc command line
options.

Please find two patches, one which is refurbishing the ARC options,
and the second one which updates the ARC specific tests.

Claudiu Zissulescu (2):
  New option handling, refurbish multilib support.
  Update target specific tests.

 gcc/common/config/arc/arc-common.c               | 162 ++++++++++++------
 gcc/config.gcc                                   |  47 +++---
 gcc/config/arc/arc-arch.h                        | 120 +++++++++++++
 gcc/config/arc/arc-arches.def                    |  35 ++++
 gcc/config/arc/arc-c.def                         |   4 +
 gcc/config/arc/arc-cpus.def                      |  47 ++++++
 gcc/config/arc/arc-options.def                   |  69 ++++++++
 gcc/config/arc/arc-opts.h                        |  47 +++++-
 gcc/config/arc/arc-protos.h                      |   1 -
 gcc/config/arc/arc-tables.opt                    |  90 ++++++++++
 gcc/config/arc/arc.c                             | 186 +++++++++++----------
 gcc/config/arc/arc.h                             |  91 +++++-----
 gcc/config/arc/arc.md                            |   5 -
 gcc/config/arc/arc.opt                           | 109 ++++--------
 gcc/config/arc/driver-arc.c                      |  80 +++++++++
 gcc/config/arc/genmultilib.awk                   | 204 +++++++++++++++++++++++
 gcc/config/arc/genoptions.awk                    |  86 ++++++++++
 gcc/config/arc/t-arc                             |  19 +++
 gcc/config/arc/t-arc-newlib                      |  46 -----
 gcc/config/arc/t-arc-uClibc                      |  20 ---
 gcc/config/arc/t-multilib                        |  51 ++++++
 gcc/config/arc/t-uClibc                          |  20 +++
 gcc/doc/invoke.texi                              |  86 ++++++++--
 gcc/testsuite/gcc.target/arc/abitest.S           |  31 ++++
 gcc/testsuite/gcc.target/arc/arc.exp             |  66 +++++++-
 gcc/testsuite/gcc.target/arc/barrel-shifter-1.c  |   2 +-
 gcc/testsuite/gcc.target/arc/builtin_simd.c      |   1 +
 gcc/testsuite/gcc.target/arc/builtin_simdarc.c   |   1 +
 gcc/testsuite/gcc.target/arc/cmem-1.c            |   1 +
 gcc/testsuite/gcc.target/arc/cmem-2.c            |   1 +
 gcc/testsuite/gcc.target/arc/cmem-3.c            |   1 +
 gcc/testsuite/gcc.target/arc/cmem-4.c            |   1 +
 gcc/testsuite/gcc.target/arc/cmem-5.c            |   1 +
 gcc/testsuite/gcc.target/arc/cmem-6.c            |   1 +
 gcc/testsuite/gcc.target/arc/cmem-7.c            |   1 +
 gcc/testsuite/gcc.target/arc/extzv-1.c           |   1 +
 gcc/testsuite/gcc.target/arc/insv-1.c            |   1 +
 gcc/testsuite/gcc.target/arc/insv-2.c            |   1 +
 gcc/testsuite/gcc.target/arc/interrupt-1.c       |   7 +-
 gcc/testsuite/gcc.target/arc/interrupt-2.c       |   1 +
 gcc/testsuite/gcc.target/arc/interrupt-3.c       |   2 +-
 gcc/testsuite/gcc.target/arc/jump-around-jump.c  |   2 +-
 gcc/testsuite/gcc.target/arc/mA6.c               |   1 +
 gcc/testsuite/gcc.target/arc/mA7.c               |   1 +
 gcc/testsuite/gcc.target/arc/mARC600.c           |   1 +
 gcc/testsuite/gcc.target/arc/mARC601.c           |   3 +-
 gcc/testsuite/gcc.target/arc/mARC700.c           |   1 +
 gcc/testsuite/gcc.target/arc/mcpu-arc600.c       |   3 +-
 gcc/testsuite/gcc.target/arc/mcpu-arc601.c       |   5 +-
 gcc/testsuite/gcc.target/arc/mcpu-arc700.c       |   3 +-
 gcc/testsuite/gcc.target/arc/mcrc.c              |   8 -
 gcc/testsuite/gcc.target/arc/mdpfp.c             |   1 +
 gcc/testsuite/gcc.target/arc/mdsp-packa.c        |   9 -
 gcc/testsuite/gcc.target/arc/mdvbf.c             |   9 -
 gcc/testsuite/gcc.target/arc/mmac-24.c           |   8 -
 gcc/testsuite/gcc.target/arc/mmac-d16.c          |   9 -
 gcc/testsuite/gcc.target/arc/mno-crc.c           |  11 --
 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c     |  11 --
 gcc/testsuite/gcc.target/arc/mno-dvbf.c          |  11 --
 gcc/testsuite/gcc.target/arc/mno-mac-24.c        |  11 --
 gcc/testsuite/gcc.target/arc/mno-mac-d16.c       |  11 --
 gcc/testsuite/gcc.target/arc/mno-rtsc.c          |  11 --
 gcc/testsuite/gcc.target/arc/mno-xy.c            |  10 --
 gcc/testsuite/gcc.target/arc/movb-1.c            |   1 +
 gcc/testsuite/gcc.target/arc/movb-2.c            |   1 +
 gcc/testsuite/gcc.target/arc/movb-3.c            |   1 +
 gcc/testsuite/gcc.target/arc/movb-4.c            |   1 +
 gcc/testsuite/gcc.target/arc/movb-5.c            |   1 +
 gcc/testsuite/gcc.target/arc/movb_cl-1.c         |   1 +
 gcc/testsuite/gcc.target/arc/movb_cl-2.c         |   1 +
 gcc/testsuite/gcc.target/arc/movbi_cl-1.c        |   1 +
 gcc/testsuite/gcc.target/arc/movh_cl-1.c         |   1 +
 gcc/testsuite/gcc.target/arc/movl-1.c            |   1 +
 gcc/testsuite/gcc.target/arc/mrtsc.c             |   8 -
 gcc/testsuite/gcc.target/arc/mspfp.c             |   1 +
 gcc/testsuite/gcc.target/arc/mul64.c             |   3 +-
 gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c |   5 +-
 gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c |   4 +-
 gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c      |   1 +
 gcc/testsuite/gcc.target/arc/nps400-1.c          |   1 +
 gcc/testsuite/gcc.target/arc/trsub.c             |   1 +
 gcc/testsuite/gcc.target/arc/va_args-1.c         |  16 ++
 gcc/testsuite/gcc.target/arc/va_args-2.c         |  14 ++
 gcc/testsuite/gcc.target/arc/va_args-3.c         |  15 ++
 84 files changed, 1447 insertions(+), 518 deletions(-)
 create mode 100644 gcc/config/arc/arc-arch.h
 create mode 100644 gcc/config/arc/arc-arches.def
 create mode 100644 gcc/config/arc/arc-cpus.def
 create mode 100644 gcc/config/arc/arc-options.def
 create mode 100644 gcc/config/arc/arc-tables.opt
 create mode 100644 gcc/config/arc/driver-arc.c
 create mode 100644 gcc/config/arc/genmultilib.awk
 create mode 100644 gcc/config/arc/genoptions.awk
 delete mode 100644 gcc/config/arc/t-arc-newlib
 delete mode 100644 gcc/config/arc/t-arc-uClibc
 create mode 100644 gcc/config/arc/t-multilib
 create mode 100644 gcc/config/arc/t-uClibc
 create mode 100644 gcc/testsuite/gcc.target/arc/abitest.S
 delete mode 100644 gcc/testsuite/gcc.target/arc/mcrc.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mdsp-packa.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mdvbf.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-24.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-d16.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-crc.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dvbf.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-24.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-d16.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-rtsc.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-xy.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mrtsc.c
 create mode 100644 gcc/testsuite/gcc.target/arc/va_args-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/va_args-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/va_args-3.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/2] [ARC] New option handling, refurbish multilib support.
  2016-05-30 14:07 [PATCH 0/2] [ARC] Refurbish backend options Claudiu Zissulescu
@ 2016-05-30 14:19 ` Claudiu Zissulescu
  2016-10-10 13:28   ` [PATCH] " Claudiu Zissulescu
  2016-05-30 14:21 ` [PATCH 2/2] [ARC] Update target specific tests Claudiu Zissulescu
  2016-06-15  7:06 ` [PATCH 0/2] [ARC] Refurbish backend options Claudiu Zissulescu
  2 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-05-30 14:19 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, gnu, Francois.Bedard

Overhaul of ARC options, and multilib support for various cpus.

OK to apply?
Claudiu

gcc/
2016-05-09  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-arch.h: New file.
	* config/arc/arc-arches.def: Likewise.
	* config/arc/arc-cpus.def: Likewise.
	* config/arc/arc-options.def: Likewise.
	* config/arc/t-multilib: Likewise.
	* config/arc/genmultilib.awk: Likewise.
	* config/arc/genoptions.awk: Likewise.
	* config/arc/arc-tables.opt: Likewise.
	* config/arc/driver-arc.c: Likewise.
	* common/config/arc/arc-common.c (arc_handle_option): Trace
	toggled options.
	* config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra
	options; check for supported cpu against arc-cpus.def file.
	(arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define
	TARGET_CPU_BUILD macro; add driver-arc.o as an extra object.
	* config/arc/arc-c.def: Add emacs local variables.
	* config/arc/arc-opts.h (processor_type): Use arc-cpus.def file.
	(FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA)
	(FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL)
	(FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines.
	(DEFAULT_arc_fpu_build): Define.
	(DEFAULT_arc_mpy_option): Define.
	* config/arc/arc-protos.h (arc_init): Delete.
	* config/arc/arc.c (arc_cpu_name): New variable.
	(arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs)
	(arc_arc700, arc_arc600, arc_arc601): New variable.
	(arc_init): Add static; remove selection of default tune value,
	cleanup obsolete error messages.
	(arc_override_options): Make use of .def files for selecting the
	right cpu and option configurations.
	* config/arc/arc.h (stdbool.h): Include.
	(TARGET_CPU_DEFAULT): Define.
	(CPP_SPEC): Remove mcpu=NPS400 handling.
	(arc_cpu_to_as): Declare.
	(EXTRA_SPEC_FUNCTIONS): Define.
	(OPTION_DEFAULT_SPECS): Likewise.
	(ASM_DEFAULT): Remove.
	(ASM_SPEC): Use arc_cpu_to_as.
	(DRIVER_SELF_SPECS): Remove deprecated options.
	(arc_arc700, arc_arc600, arc_arc601, arc_arcem, arc_archs):
	Declare.
	(TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM)
	(TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_arc*
	variables.
	(MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT.
	* config/arc/arc.md (attr_cpu): Remove.
	* config/arc/arc.opt (arc_mpy_option): Make it target variable.
	(mno-mpy): Deprecate.
	(mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM)
	(mcpu=ARCHS): Remove.
	(mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc):
	Deprecate.
	(mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove.
	(arc_fpu): Use new defines.
	(arc_seen_options): New target variable.
	* config/arc/t-arc (driver-arc.o): New target.
	(arc-cpus, t-multilib, arc-tables.opt): Likewise.
	* config/arc/t-arc-newlib: Delete.
	* config/arc/t-arc-uClibc: Renamed to t-uClibc.
	* doc/invoke.texi (ARC): Update arc options.
---
 gcc/common/config/arc/arc-common.c | 162 ++++++++++++++++++++---------
 gcc/config.gcc                     |  47 +++++----
 gcc/config/arc/arc-arch.h          | 120 ++++++++++++++++++++++
 gcc/config/arc/arc-arches.def      |  35 +++++++
 gcc/config/arc/arc-c.def           |   4 +
 gcc/config/arc/arc-cpus.def        |  47 +++++++++
 gcc/config/arc/arc-options.def     |  69 +++++++++++++
 gcc/config/arc/arc-opts.h          |  47 +++++++--
 gcc/config/arc/arc-protos.h        |   1 -
 gcc/config/arc/arc-tables.opt      |  90 ++++++++++++++++
 gcc/config/arc/arc.c               | 186 ++++++++++++++++++---------------
 gcc/config/arc/arc.h               |  91 ++++++++---------
 gcc/config/arc/arc.md              |   5 -
 gcc/config/arc/arc.opt             | 109 ++++++--------------
 gcc/config/arc/driver-arc.c        |  80 +++++++++++++++
 gcc/config/arc/genmultilib.awk     | 204 +++++++++++++++++++++++++++++++++++++
 gcc/config/arc/genoptions.awk      |  86 ++++++++++++++++
 gcc/config/arc/t-arc               |  19 ++++
 gcc/config/arc/t-arc-newlib        |  46 ---------
 gcc/config/arc/t-arc-uClibc        |  20 ----
 gcc/config/arc/t-multilib          |  51 ++++++++++
 gcc/config/arc/t-uClibc            |  20 ++++
 gcc/doc/invoke.texi                |  86 +++++++++++++---
 23 files changed, 1249 insertions(+), 376 deletions(-)
 create mode 100644 gcc/config/arc/arc-arch.h
 create mode 100644 gcc/config/arc/arc-arches.def
 create mode 100644 gcc/config/arc/arc-cpus.def
 create mode 100644 gcc/config/arc/arc-options.def
 create mode 100644 gcc/config/arc/arc-tables.opt
 create mode 100644 gcc/config/arc/driver-arc.c
 create mode 100644 gcc/config/arc/genmultilib.awk
 create mode 100644 gcc/config/arc/genoptions.awk
 delete mode 100644 gcc/config/arc/t-arc-newlib
 delete mode 100644 gcc/config/arc/t-arc-uClibc
 create mode 100644 gcc/config/arc/t-multilib
 create mode 100644 gcc/config/arc/t-uClibc

diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index f5b9c6d..0141e3d 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -2,6 +2,7 @@
    Copyright (C) 1994-2016 Free Software Foundation, Inc.
    Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
 		on behalf of Synopsys Inc.
+		Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
 
 This file is part of GCC.
 
@@ -62,17 +63,19 @@ static const struct default_options arc_option_optimization_table[] =
 
 /*  Process options.  */
 static bool
-arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
+arc_handle_option (struct gcc_options *opts,
+		   struct gcc_options *opts_set ATTRIBUTE_UNUSED,
 		   const struct cl_decoded_option *decoded,
 		   location_t loc)
 {
   size_t code = decoded->opt_index;
   int value = decoded->value;
   const char *arg = decoded->arg;
+  static int mcpu_seen = PROCESSOR_NONE;
+  char *p;
 
   switch (code)
     {
-      static int mcpu_seen = PROCESSOR_NONE;
     case OPT_mcpu_:
       /* N.B., at this point arc_cpu has already been set to its new value by
 	 our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless.  */
@@ -80,71 +83,130 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
       if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
 	warning_at (loc, 0, "multiple -mcpu= options specified.");
       mcpu_seen = value;
+      break;
+
+    case OPT_mmpy_option_:
+      p = ASTRDUP (arg);
 
-      switch (value)
+      if (!strcmp (p, "0")
+	  || !strcmp (p, "none"))
+	opts->x_arc_mpy_option = 0;
+      else if (!strcmp (p, "1")
+	  || !strcmp (p, "w"))
 	{
-	case PROCESSOR_NPS400:
-	  if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) )
-	    opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1;
-	  /* Fall through */
-	case PROCESSOR_ARC600:
-	case PROCESSOR_ARC700:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARC601:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARCHS:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags |= MASK_CODE_DENSITY;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags |= MASK_NORM_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags |= MASK_SWAP_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags |= MASK_DIVREM;	  /* Default: on.  */
-	  break;
-
-	case PROCESSOR_ARCEM:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags &= ~MASK_CODE_DENSITY;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags &= ~MASK_NORM_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags &= ~MASK_SWAP_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags &= ~MASK_DIVREM;	  /* Default: off.  */
-	  break;
-	default:
-	  gcc_unreachable ();
+	  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);
+
       break;
 
-    case OPT_mmpy_option_:
-      if (value < 0 || value > 9)
-	error_at (loc, "bad value %qs for -mmpy-option switch", arg);
+    case OPT_mcode_density:
+      opts->x_arc_seen_options |= MASK_CODE_DENSITY;
+      break;
+
+    case OPT_mdiv_rem:
+      opts->x_arc_seen_options |= MASK_DIVREM;
+      break;
+
+    case OPT_mnorm:
+      opts->x_arc_seen_options |= MASK_NORM_SET;
+      break;
+
+    case OPT_matomic:
+      opts->x_arc_seen_options |= MASK_ATOMIC;
+      break;
+
+    case OPT_mll64:
+      opts->x_arc_seen_options |= MASK_LL64;
+      break;
+
+    case OPT_mbarrel_shifter:
+      opts->x_arc_seen_options |= MASK_BARREL_SHIFTER;
+      break;
+
+    case OPT_mswap:
+      opts->x_arc_seen_options |= MASK_SWAP_SET;
+      break;
+
+    case OPT_mmul64:
+      opts->x_arc_seen_options |= MASK_MUL64_SET;
+      break;
+
+    case OPT_mmul32x16:
+      opts->x_arc_seen_options |= MASK_MULMAC_32BY16_SET;
+      break;
+
+    case OPT_mEA:
+      opts->x_arc_seen_options |= MASK_EA_SET;
+      break;
+
+    case OPT_mspfp:
+    case OPT_mspfp_compact:
+    case OPT_mspfp_fast:
+      opts->x_arc_seen_options |= MASK_SPFP_COMPACT_SET;
+      break;
+
+    case OPT_mdpfp:
+    case OPT_mdpfp_compact:
+    case OPT_mdpfp_fast:
+      opts->x_arc_seen_options |= MASK_DPFP_COMPACT_SET;
+      break;
+
+    case OPT_margonaut:
+      opts->x_arc_seen_options |= MASK_ARGONAUT_SET;
+      break;
+
+    case OPT_msimd:
+      opts->x_arc_seen_options |= MASK_SIMD_SET;
+      break;
+
+    default:
       break;
     }
 
   return true;
 }
 
+#undef  TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
+
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
 #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
-#define TARGET_HANDLE_OPTION arc_handle_option
 
 #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
 
-/* We default to ARC700, which has the barrel shifter enabled.  */
-#define TARGET_DEFAULT_TARGET_FLAGS \
-  (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET)
 
+#undef  TARGET_HANDLE_OPTION
+#define TARGET_HANDLE_OPTION arc_handle_option
 
 #include "common/common-target-def.h"
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 9a45d88..c32c360 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -325,6 +325,7 @@ arc*-*-*)
 	cpu_type=arc
 	c_target_objs="arc-c.o"
 	cxx_target_objs="arc-c.o"
+	extra_options="${extra_options} arc/arc-tables.opt"
 	;;
 arm*-*-*)
 	cpu_type=arm
@@ -997,13 +998,12 @@ alpha*-dec-*vms*)
 	;;
 arc*-*-elf*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
-	tmake_file="arc/t-arc-newlib arc/t-arc"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
+	tmake_file="arc/t-multilib arc/t-arc"
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -1020,15 +1020,14 @@ arc*-*-elf*)
 	;;
 arc*-*-linux-uclibc*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
-	tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc"
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
+	tmake_file="${tmake_file} arc/t-uClibc arc/t-arc"
 	tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0"
 	tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -3652,15 +3651,19 @@ case "${target}" in
 		done
 		;;
 
-	arc*-*-*) # was:	arc*-*-linux-uclibc)
+	arc*-*-*)
 		supported_defaults="cpu"
-		case $with_cpu in
-		  arc600|arc601|arc700)
-			;;
-		  *) echo "Unknown cpu type"
-			exit 1
-			;;
-		esac
+
+		if [ x"$with_cpu" = x ] \
+		    || grep "^ARC_CPU ($with_cpu," \
+		       ${srcdir}/config/arc/arc-cpus.def \
+		       > /dev/null; then
+		 # Ok
+		 true
+		else
+		 echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
+		 exit 1
+		fi
 		;;
 
 	arm*-*-*)
diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
new file mode 100644
index 0000000..7994543
--- /dev/null
+++ b/gcc/config/arc/arc-arch.h
@@ -0,0 +1,120 @@
+/* Definitions of types that are used to store ARC architecture and
+   device information.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu (claziss@synopsys.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ARC_ARCH_H
+#define GCC_ARC_ARCH_H
+
+#ifndef IN_LIBGCC2
+/* Architecture selection types.  */
+
+enum cpu_flags
+  {
+#define ARC_OPT(NAME, CODE, MASK, DOC)	    NAME = CODE,
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE,
+#include "arc-options.def"
+#undef ARC_OPT
+#undef ARC_OPTX
+    FL_END
+  };
+
+
+/* ARC architecture variants.  */
+
+enum base_architecture
+  {
+    BASE_ARCH_NONE,
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)  BASE_ARCH_##ARCH,
+#include "arc-arches.def"
+#undef ARC_ARCH
+    BASE_ARCH_END
+  };
+
+
+/* Tune variants.  Needs to match the attr_tune enum.  */
+
+enum arc_tune_attr
+  {
+    ARC_TUNE_NONE,
+    ARC_TUNE_ARC600,
+    ARC_TUNE_ARC700_4_2_STD,
+    ARC_TUNE_ARC700_4_2_XMAC
+  };
+
+/* CPU specific properties.  */
+
+typedef struct
+{
+  /* CPU name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* Specific flags.  */
+  const unsigned long long flags;
+
+  /* Tune value.  */
+  enum arc_tune_attr tune;
+} arc_cpu_t;
+
+
+/* Architecture specific propoerties.  */
+
+typedef struct
+{
+  /* Architecture name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* All allowed flags for this architecture.  */
+  const unsigned long long flags;
+
+  /* Default flags for this architecture.  It is a subset of
+     FLAGS.  */
+  const unsigned long long dflags;
+} arc_arch_t;
+
+
+
+const arc_arch_t arc_arch_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, 0},
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)	\
+    {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS},
+#include "arc-arches.def"
+#undef ARC_ARCH
+    {NULL, BASE_ARCH_END, 0, 0}
+  };
+
+const arc_cpu_t arc_cpu_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE},
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
+    {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE},
+#include "arc-cpus.def"
+#undef ARC_CPU
+    {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE}
+  };
+
+#endif
+#endif /* GCC_ARC_ARCH_H */
diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
new file mode 100644
index 0000000..bd76124
--- /dev/null
+++ b/gcc/config/arc/arc-arches.def
@@ -0,0 +1,35 @@
+/* ARC ARCH architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
+	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
+	  | FL_SIMD | FL_FPUDA, 0)
+ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
+	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
+	  | FL_FPUS | FL_FPUD,						\
+	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
+ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
+	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
+ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
+	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
+	  FL_BS | FL_NORM | FL_SWAP)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
index 065e973..4cfd7b6 100644
--- a/gcc/config/arc/arc-c.def
+++ b/gcc/config/arc/arc-c.def
@@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__",     TARGET_EM)
 ARC_C_DEF ("__HS__",     TARGET_HS)
 ARC_C_DEF ("__Xnorm",    TARGET_NORM)
 ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
new file mode 100644
index 0000000..381507c
--- /dev/null
+++ b/gcc/config/arc/arc-cpus.def
@@ -0,0 +1,47 @@
+/* ARC CPU architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+ARC_CPU (em,	    em, 0, NONE)
+ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
+ARC_CPU (em4,	    em, FL_CD, NONE)
+ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
+ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
+ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
+
+ARC_CPU (hs,	     hs, 0, NONE)
+ARC_CPU (archs,	     hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs34,	     hs, FL_MPYOPT_2, NONE)
+ARC_CPU (hs38,	     hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE)
+
+ARC_CPU (arc600,	  6xx, FL_BS, ARC600)
+ARC_CPU (arc600_norm,	  6xx, FL_BS|FL_NORM, ARC600)
+ARC_CPU (arc600_mul64,	  6xx, FL_BS|FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600)
+ARC_CPU (arc601,	  6xx, 0, ARC600)
+ARC_CPU (arc601_norm,	  6xx, FL_NORM, ARC600)
+ARC_CPU (arc601_mul64,	  6xx, FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600)
+
+ARC_CPU (arc700, 700, 0, ARC700_4_2_STD)
+ARC_CPU (nps400, 700, 0, ARC700_4_2_STD)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
new file mode 100644
index 0000000..083719a
--- /dev/null
+++ b/gcc/config/arc/arc-options.def
@@ -0,0 +1,69 @@
+/* ARC options.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
+ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
+ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
+
+ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
+ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
+ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
+ARC_OPT (FL_SWAP,     (1ULL << 7), MASK_SWAP_SET,	   "swap")
+ARC_OPT (FL_MUL64,    (1ULL << 8), MASK_MUL64_SET,	   "mul64")
+ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16")
+
+ARC_OPT (FL_EA,	      (1ULL << 11), MASK_EA_SET,	   "extended arithmetics")
+ARC_OPT (FL_SPFP,     (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX")
+ARC_OPT (FL_DPFP,     (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX")
+ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET,	   "argonaut")
+ARC_OPT (FL_SIMD,     (1ULL << 15), MASK_SIMD_SET,	   "simd")
+
+ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w")
+ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1")
+ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2")
+ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3")
+ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4")
+ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5")
+ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy")
+ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd")
+ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw")
+
+ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option")
+ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option")
+
+ARC_OPTX (FL_FPU_FPUS,	    (1ULL << 26), arc_fpu_build, FPU_FPUS,	"mfpu=fpus")
+ARC_OPTX (FL_FPU_FPUS_DIV,  (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV,	"mfpu=fpus_div")
+ARC_OPTX (FL_FPU_FPUS_FMA,  (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA,	"mfpu=fpus_fma")
+ARC_OPTX (FL_FPU_FPUS_ALL,  (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL,	"mfpu=fpus_all")
+ARC_OPTX (FL_FPU_FPUDA,	    (1ULL << 30), arc_fpu_build, FPU_FPUDA,	"mfpu=fpuda")
+ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div")
+ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma")
+ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all")
+ARC_OPTX (FL_FPU_FPUD,	    (1ULL << 34), arc_fpu_build, FPU_FPUD,	"mfpu=fpud")
+ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV,	"mfpu=fpud_div")
+ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA,	"mfpu=fpud_fma")
+ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL,	"mfpu=fpud_all")
+
+ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
+ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
+ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
index cbd7898..81446b4 100644
--- a/gcc/config/arc/arc-opts.h
+++ b/gcc/config/arc/arc-opts.h
@@ -18,15 +18,16 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef ARC_OPTS_H
+#define ARC_OPTS_H
+
 enum processor_type
 {
-  PROCESSOR_NONE,
-  PROCESSOR_ARC600,
-  PROCESSOR_ARC601,
-  PROCESSOR_ARC700,
-  PROCESSOR_NPS400,
-  PROCESSOR_ARCEM,
-  PROCESSOR_ARCHS
+  PROCESSOR_NONE = 0,
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)  PROCESSOR_##NAME,
+#include "arc-cpus.def"
+#undef ARC_CPU
+  PROCESSOR_generic
 };
 
 /* Single precision floating point.  */
@@ -48,3 +49,35 @@ enum processor_type
 /* Double precision floating point assist operations.  */
 #define FPX_DP    0x0100
 
+/* fpus option combi.  */
+#define FPU_FPUS  (FPU_SP | FPU_SC)
+/* fpud option combi.  */
+#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+/* fpuda option combi.  */
+#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
+/* fpuda_div option combi.  */
+#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+/* fpuda_fma option combi.  */
+#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+/* fpuda_all option combi.  */
+#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+/* fpus_div option combi.  */
+#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
+/* fpus_fma option combi.  */
+#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
+/* fpus_all option combi.  */
+#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+/* fpud_div option combi.  */
+#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
+/* fpud_fma option combi.  */
+#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
+/* fpud_all option combi.  */
+#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+
+/* Default FPU option value.  */
+#define DEFAULT_arc_fpu_build 0x10000000
+
+/* Default MPY option value.  */
+#define DEFAULT_arc_mpy_option -1
+
+#endif /* ARC_OPTS_H */
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index b6ed392..0e94766 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
 #endif /* TREE_CODE */
 
 
-extern void arc_init (void);
 extern unsigned int arc_compute_frame_size (int);
 extern bool arc_ccfsm_branch_deleted_p (void);
 extern void arc_ccfsm_record_branch_deleted (void);
diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
new file mode 100644
index 0000000..0e7c50c
--- /dev/null
+++ b/gcc/config/arc/arc-tables.opt
@@ -0,0 +1,90 @@
+; Auto-generated Makefile Snip
+; Generated by    : ./gcc/config/arc/genoptions.awk
+; Generated from  : ./gcc/config/arc/arc-cpu.def
+;
+; Copyright (C) 2016 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+Enum
+Name(processor_type) Type(enum processor_type)
+Known ARC CPUs (for use with the -mcpu= option):
+
+EnumValue
+Enum(processor_type) String(em) Value(PROCESSOR_em)
+
+EnumValue
+Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
+
+EnumValue
+Enum(processor_type) String(em4) Value(PROCESSOR_em4)
+
+EnumValue
+Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips)
+
+EnumValue
+Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
+
+EnumValue
+Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
+
+EnumValue
+Enum(processor_type) String(hs) Value(PROCESSOR_hs)
+
+EnumValue
+Enum(processor_type) String(archs) Value(PROCESSOR_archs)
+
+EnumValue
+Enum(processor_type) String(hs34) Value(PROCESSOR_hs34)
+
+EnumValue
+Enum(processor_type) String(hs38) Value(PROCESSOR_hs38)
+
+EnumValue
+Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux)
+
+EnumValue
+Enum(processor_type) String(arc600) Value(PROCESSOR_arc600)
+
+EnumValue
+Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm)
+
+EnumValue
+Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64)
+
+EnumValue
+Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc601) Value(PROCESSOR_arc601)
+
+EnumValue
+Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm)
+
+EnumValue
+Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64)
+
+EnumValue
+Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc700) Value(PROCESSOR_arc700)
+
+EnumValue
+Enum(processor_type) String(nps400) Value(PROCESSOR_nps400)
+
+
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index c0aa075..985df81 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -64,7 +64,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 
 /* Which cpu we're compiling for (ARC600, ARC601, ARC700).  */
-static const char *arc_cpu_string = "";
+static char arc_cpu_name[10] = "";
+static const char *arc_cpu_string = arc_cpu_name;
 
 /* ??? Loads can handle any constant, stores can only handle small ones.  */
 /* OTOH, LIMMs cost extra, so their usefulness is limited.  */
@@ -241,6 +242,16 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
 						enum by_pieces_operation op,
 						bool);
 
+static const arc_cpu_t *arc_selected_cpu;
+static const arc_arch_t *arc_selected_arch;
+
+/* Global var which sets the current compilation architecture.  */
+bool arc_arcem = false;
+bool arc_archs = false;
+bool arc_arc700 = false;
+bool arc_arc600 = false;
+bool arc_arc601 = false;
+
 /* Implements target hook vector_mode_supported_p.  */
 
 static bool
@@ -668,47 +679,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
 
 /* Called by OVERRIDE_OPTIONS to initialize various things.  */
 
-void
+static void
 arc_init (void)
 {
-  enum attr_tune tune_dflt = TUNE_NONE;
-
-  switch (arc_cpu)
-    {
-    case PROCESSOR_ARC600:
-      arc_cpu_string = "ARC600";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC601:
-      arc_cpu_string = "ARC601";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC700:
-      arc_cpu_string = "ARC700";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_NPS400:
-      arc_cpu_string = "NPS400";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_ARCEM:
-      arc_cpu_string = "EM";
-      break;
-
-    case PROCESSOR_ARCHS:
-      arc_cpu_string = "HS";
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  if (arc_tune == TUNE_NONE)
-    arc_tune = tune_dflt;
   /* Note: arc_multcost is only used in rtx_cost if speed is true.  */
   if (arc_multcost < 0)
     switch (arc_tune)
@@ -739,18 +712,10 @@ arc_init (void)
 	break;
       }
 
-  /* Support mul64 generation only for ARC600.  */
-  if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul64 not supported for ARC700 or ARCv2");
-
   /* MPY instructions valid only for ARC700 or ARCv2.  */
   if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
       error ("-mno-mpy supported only for ARC700 or ARCv2");
 
-  /* mul/mac instructions only for ARC600.  */
-  if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul32x16 supported only for ARC600 or ARC601");
-
   if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
       error ("-mno-dpfp-lrsr supported only with -mdpfp");
 
@@ -763,23 +728,11 @@ arc_init (void)
   if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
     error ("-mspfp_fast not available on ARC600 or ARC601");
 
-  /* FPX-3. No FPX extensions on pre-ARC600 cores.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
-    error ("FPX extensions not available on pre-ARC600 cores");
-
-  /* FPX-4.  No FPX extensions mixed with FPU extensions for ARC HS
-     cpus.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && TARGET_HARD_FLOAT
-      && TARGET_HS)
+  /* FPX-4.  No FPX extensions mixed with FPU extensions.  */
+  if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
+      && TARGET_HARD_FLOAT)
     error ("No FPX/FPU mixing allowed");
 
-  /* Only selected multiplier configurations are available for HS.  */
-  if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
-		    || (arc_mpy_option == 1)))
-    error ("This multiplier configuration is not available for HS cores");
-
   /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic.  */
   if (flag_pic && TARGET_ARC600_FAMILY)
     {
@@ -789,26 +742,6 @@ arc_init (void)
       flag_pic = 0;
     }
 
-  if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS))
-    error ("-matomic is only supported for ARC700 or ARC HS cores");
-
-  /* ll64 ops only available for HS.  */
-  if (TARGET_LL64 && !TARGET_HS)
-    error ("-mll64 is only supported for ARC HS cores");
-
-  /* FPU support only for V2.  */
-  if (TARGET_HARD_FLOAT)
-    {
-      if (TARGET_EM
-	  && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
-	error ("FPU double precision options are available for ARC HS only");
-      if (TARGET_HS && (arc_fpu_build & FPX_DP))
-	error ("FPU double precision assist "
-	       "options are not available for ARC HS");
-      if (!TARGET_HS && !TARGET_EM)
-	error ("FPU options are available for ARCv2 architecture only");
-    }
-
   arc_init_reg_tables ();
 
   /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
@@ -853,7 +786,92 @@ static void
 arc_override_options (void)
 {
   if (arc_cpu == PROCESSOR_NONE)
-    arc_cpu = PROCESSOR_ARC700;
+    arc_cpu = TARGET_CPU_DEFAULT;
+
+  /* Set the default cpu options.  */
+  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
+  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
+
+  /* Set the architectures.  */
+  switch (arc_selected_arch->arch)
+    {
+    case BASE_ARCH_em:
+      arc_arcem = true;
+      arc_cpu_string = "EM";
+      break;
+    case BASE_ARCH_hs:
+      arc_archs = true;
+      arc_cpu_string = "HS";
+      break;
+    case BASE_ARCH_700:
+      arc_arc700 = true;
+      arc_cpu_string = "ARC700";
+      break;
+    case BASE_ARCH_6xx:
+      arc_cpu_string = "ARC600";
+      if (arc_selected_cpu->flags & FL_BS)
+	arc_arc600 = true;
+      else
+	arc_arc601 = true;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
+     specific flags are set in arc-common.c.  The architecture forces
+     the default hardware configurations in, regardless what command
+     line options are saying.  The CPU optional hw options can be
+     turned on or off.  */
+#define ARC_OPT(NAME, CODE, MASK, DOC)		\
+  do {						\
+    if ((arc_selected_cpu->flags & CODE)	\
+	&& ((arc_seen_options & MASK) == 0))	\
+      target_flags |= MASK;			\
+    if (arc_selected_arch->dflags & CODE)	\
+      target_flags |= MASK;			\
+  } while (0);
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
+  do {						\
+    if ((arc_selected_cpu->flags & CODE)	\
+	&& (VAR == DEFAULT_##VAR))		\
+      VAR = VAL;				\
+    if (arc_selected_arch->dflags & CODE)	\
+      VAR = VAL;				\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Check options against architecture options.  Throw an error if
+     option is not allowed.  */
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
+  do {								\
+    if ((VAR == VAL)						\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      {								\
+	error ("%s is not available for %s architecture",	\
+	       DOC, arc_selected_arch->name);			\
+      }								\
+  } while (0);
+#define ARC_OPT(NAME, CODE, MASK, DOC)				\
+  do {								\
+    if ((target_flags & MASK)					\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      error ("%s is not available for %s architecture",		\
+	     DOC, arc_selected_arch->name);			\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Set Tune option.  */
+  if (arc_tune == TUNE_NONE)
+    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
 
   if (arc_size_opt_level == 3)
     optimize_size = 1;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index c02e1cd..f1705d5 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ARC_H
 #define GCC_ARC_H
 
+#include <stdbool.h>
+
 /* Things to do:
 
    - incscc, decscc?
@@ -39,6 +41,10 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
 #define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
 
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT	PROCESSOR_arc700
+#endif
+
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)	\
 	((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
@@ -74,9 +80,11 @@ along with GCC; see the file COPYING3.  If not see
       GNU_USER_TARGET_OS_CPP_BUILTINS (); \
     } \
   while (0)
-#endif
 
-/* Match the macros used in the assembler.  */
+#endif /* DEFAULT_LIBC == LIBC_UCLIBC */
+
+/* Macros enabled by specific command line option.  FIXME: to be
+   deprecatd.  */
 #define CPP_SPEC "\
 %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \
 %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \
@@ -85,34 +93,22 @@ along with GCC; see the file COPYING3.  If not see
 %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \
 %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \
 %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \
-%{mcpu=NPS400:-D__NPS400__} \
-%{mcpu=nps400:-D__NPS400__} \
-"
+%{mcpu=nps400:-D__NPS400__}"
 
 #define CC1_SPEC "\
 %{EB:%{EL:%emay not use both -EB and -EL}} \
 %{EB:-mbig-endian} %{EL:-mlittle-endian} \
 "
+extern const char *arc_cpu_to_as (int argc, const char **argv);
+
+#define EXTRA_SPEC_FUNCTIONS			\
+  { "cpu_to_as", arc_cpu_to_as },
+
+#define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "			\
+  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
 
-#define ASM_DEFAULT "-mARC700 -mEA"
-
-#define ASM_SPEC  "\
-%{mbig-endian|EB:-EB} %{EL} \
-%{mcpu=ARC600:-mARC600} \
-%{mcpu=ARC601:-mARC601} \
-%{mcpu=ARC700:-mARC700} \
-%{mcpu=ARC700:-mEA} \
-%{!mcpu=*:" ASM_DEFAULT "} \
-%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \
-%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \
-%{msimd} \
-%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \
-%{mcpu=ARC700|!mcpu=*:%{mlock}} \
-%{mcpu=ARC700|!mcpu=*:%{mswape}} \
-%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \
-%{mcpu=ARCHS:-mHS} \
-%{mcpu=ARCEM:-mEM} \
-%{matomic:-mlock}"
+#define OPTION_DEFAULT_SPECS						\
+  {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
 
 #if DEFAULT_LIBC == LIBC_UCLIBC
 /* Note that the default is to link against dynamic libraries, if they are
@@ -196,17 +192,11 @@ along with GCC; see the file COPYING3.  If not see
 #define TARGET_MMEDIUM_CALLS_DEFAULT 0
 #endif
 
-#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \
-  "%{mARC600|mA6: -mcpu=ARC600 %<mARC600 %<mA6}" \
-  "%{mARC601: -mcpu=ARC601 %<mARC601}" \
-  "%{mARC700|mA7: -mcpu=ARC700 %<mARC700 %<mA7}" \
-  "%{mbarrel_shifte*: -mbarrel-shifte%* %<mbarrel_shifte*}" \
-  "%{mEA: -mea %<mEA}" \
-  "%{mspfp_*: -mspfp-%* %<mspfp_*}" \
-  "%{mdpfp_*: -mdpfp-%* %<mdpfp_*}" \
-  "%{mdsp_pack*: -mdsp-pack%* %<mdsp_pack*}" \
-  "%{mmac_*: -mmac-%* %<mmac_*}" \
-  "%{multcost=*: -mmultcost=%* %<multcost=*}"
+#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS		   \
+  "%{mARC600|mA6: -mcpu=arc600 %<mARC600 %<mA6 %<mARC600}"	   \
+  "%{mARC601: -mcpu=arc601 %<mARC601}"				   \
+  "%{mARC700|mA7: -mcpu=arc700 %<mARC700 %<mA7}"		   \
+  "%{mEA: -mea %<mEA}"
 
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
@@ -252,20 +242,23 @@ along with GCC; see the file COPYING3.  If not see
    use conditional execution?  */
 #define TARGET_AT_DBR_CONDEXEC  (!TARGET_ARC700 && !TARGET_V2)
 
-#define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
-#define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
-#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700	\
-		       || arc_cpu == PROCESSOR_NPS400)
-#define TARGET_EM     (arc_cpu == PROCESSOR_ARCEM)
-#define TARGET_HS     (arc_cpu == PROCESSOR_ARCHS)
-#define TARGET_V2							\
-  ((arc_cpu == PROCESSOR_ARCHS) || (arc_cpu == PROCESSOR_ARCEM))
-
-/* Recast the cpu class to be the cpu attribute.  */
-#define arc_cpu_attr ((enum attr_cpu)arc_cpu)
-
-#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mARC700" }
+extern bool arc_arcem;
+extern bool arc_archs;
+extern bool arc_arc700;
+extern bool arc_arc600;
+extern bool arc_arc601;
+
+#define TARGET_ARC600 (arc_arc600)
+#define TARGET_ARC601 (arc_arc601)
+#define TARGET_ARC700 (arc_arc700)
+#define TARGET_EM (arc_arcem)
+#define TARGET_HS (arc_archs)
+#define TARGET_V2 (TARGET_EM || TARGET_HS)
+
+#ifdef ARC_MULTILIB_CPU_DEFAULT
+# ifndef MULTILIB_DEFAULTS
+#  define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT }
+# endif
 #endif
 
 #ifndef UNALIGNED_ACCESS_DEFAULT
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 1102c53..5accf4a 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -231,11 +231,6 @@
 	 (eq_attr "is_CALL" "yes") (const_string "yes")]
 	(const_string "no")))
 
-
-;; Attribute describing the processor
-(define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
-  (const (symbol_ref "arc_cpu_attr")))
-
 ;; true for compact instructions (those with _s suffix)
 ;; "maybe" means compact unless we conditionalize the insn.
 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index d957a92..19c5deb 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -53,9 +53,12 @@ mARC700
 Target Report
 Same as -mA7.
 
+TargetVariable
+int arc_mpy_option = DEFAULT_arc_mpy_option
+
 mmpy-option=
-Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
--mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
+Target RejectNegative Joined
+-mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
 
 mdiv-rem
 Target Report Mask(DIVREM)
@@ -100,7 +103,7 @@ Target Report Mask(MUL64_SET)
 Generate mul64 and mulu64 instructions.
 
 mno-mpy
-Target Report Mask(NOMPY_SET)
+Target Report Mask(NOMPY_SET) Warn(%qs is deprecated)
 Do not generate mpy instructions for ARC700.
 
 mea
@@ -167,45 +170,6 @@ mcpu=
 Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
 -mcpu=CPU	Compile code for ARC variant CPU.
 
-Enum
-Name(processor_type) Type(enum processor_type)
-
-EnumValue
-Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(arc600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(arc601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(arcem) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(ARCHS) Value(PROCESSOR_ARCHS)
-
-EnumValue
-Enum(processor_type) String(archs) Value(PROCESSOR_ARCHS)
-
 msize-level=
 Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
 size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os.
@@ -308,25 +272,25 @@ Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
 ; Flags used by the assembler, but for which we define preprocessor
 ; macro symbols as well.
 mcrc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable variable polynomial CRC extension.
 
 mdsp-packa
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable DSP 3.1 Pack A extensions.
 
 mdvbf
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable dual viterbi butterfly extension.
 
 mmac-d16
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mmac-24
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mtelephony
-Target Report RejectNegative
+Target Report RejectNegative Warn(%qs is deprecated)
 Enable Dual and Single Operand Instructions for Telephony.
 
 mxy
@@ -343,7 +307,7 @@ Target Report
 Enable swap byte ordering extension instruction.
 
 mrtsc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable 64-bit Time-Stamp Counter extension instruction.
 
 EB
@@ -394,24 +358,6 @@ Target
 multcost=
 Target RejectNegative Joined
 
-; Unfortunately, listing the full option name gives us clashes
-; with OPT_opt_name being claimed for both opt_name and opt-name,
-; so we leave out the last character or more.
-mbarrel_shifte
-Target Joined
-
-mspfp_
-Target Joined
-
-mdpfp_
-Target Joined
-
-mdsp_pack
-Target Joined
-
-mmac_
-Target Joined
-
 matomic
 Target Report Mask(ATOMIC)
 Enable atomic instructions.
@@ -421,47 +367,47 @@ Target Report Mask(LL64)
 Enable double load/store instructions for ARC HS.
 
 mfpu=
-Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
+Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(DEFAULT_arc_fpu_build)
 Specify the name of the target floating point configuration.
 
 Enum
 Name(arc_fpu) Type(int)
 
 EnumValue
-Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
+Enum(arc_fpu) String(fpus) Value(FPU_FPUS)
 
 EnumValue
-Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+Enum(arc_fpu) String(fpud) Value(FPU_FPUD)
 
 EnumValue
-Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
+Enum(arc_fpu) String(fpuda) Value(FPU_FPUDA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_div) Value(FPU_FPUDA_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+Enum(arc_fpu) String(fpuda_fma) Value(FPU_FPUDA_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_all) Value(FPU_FPUDA_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
+Enum(arc_fpu) String(fpus_div) Value(FPU_FPUS_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
+Enum(arc_fpu) String(fpud_div) Value(FPU_FPUD_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
+Enum(arc_fpu) String(fpus_fma) Value(FPU_FPUS_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
+Enum(arc_fpu) String(fpud_fma) Value(FPU_FPUD_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+Enum(arc_fpu) String(fpus_all) Value(FPU_FPUS_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL)
 
 mtp-regno=
 Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25)
@@ -481,3 +427,6 @@ Enable use of NPS400 xld/xst extension.
 munaligned-access
 Target Report Var(unaligned_access) Init(UNALIGNED_ACCESS_DEFAULT)
 Enable unaligned word and halfword accesses to packed data.
+
+TargetVariable
+unsigned int arc_seen_options = 0
diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
new file mode 100644
index 0000000..c51b708
--- /dev/null
+++ b/gcc/config/arc/driver-arc.c
@@ -0,0 +1,80 @@
+/* Subroutines for the gcc driver.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu <claziss@synopsys.com>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+/* Returns command line parameters to pass to as.  */
+
+const char*
+arc_cpu_to_as (int argc, const char **argv)
+{
+  const char *name = NULL;
+  const arc_cpu_t *arc_selected_cpu;
+
+  /* No argument, check what is the default cpu.  */
+  if (argc == 0)
+    {
+      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
+    }
+  else
+    {
+      name = argv[0];
+      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
+	   arc_selected_cpu++)
+	{
+	  if (strcmp (arc_selected_cpu->name, name) == 0)
+	    break;
+	}
+    }
+
+  /* Checking the flags is only required with the old binutils
+     tools.  */
+  switch (arc_selected_cpu->arch)
+    {
+    case BASE_ARCH_em:
+      if (arc_selected_cpu->flags & FL_CD)
+	name = "-mcode-density";
+      else
+	name = "";
+      if (arc_selected_cpu->flags & FL_FPUDA)
+	name = concat ("-mfpuda ", name, NULL);
+      if (arc_selected_cpu->flags & FL_SPFP)
+	name = concat ("-mspfp ", name, NULL);
+      if (arc_selected_cpu->flags & FL_DPFP)
+	name = concat ("-mdpfp ", name, NULL);
+      return concat ("-mcpu=arcem ", name, NULL);
+    case BASE_ARCH_hs:
+      return "-mcpu=archs";
+    case BASE_ARCH_700:
+      return "-mcpu=arc700 -mEA";
+    case BASE_ARCH_6xx:
+      if (arc_selected_cpu->flags & FL_MUL64)
+	return "-mcpu=arc600 -mmul64 -mnorm";
+      if (arc_selected_cpu->flags & FL_MUL32x16)
+	return "-mcpu=arc600 -mdsp-packa -mnorm";
+      return "-mcpu=arc600 -mnorm";
+    default:
+      gcc_unreachable ();
+    }
+  return NULL;
+}
diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
new file mode 100644
index 0000000..b17d2b1
--- /dev/null
+++ b/gcc/config/arc/genmultilib.awk
@@ -0,0 +1,204 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+# Transform CPU Information from arc-cpu.def to a
+# Representation that is understood by GCC's multilib Machinery.
+#
+# The Script works as a Filter from STDIN to STDOUT.
+#
+# FORMAT = "Makefile": Generate Makefile Snipet that sets some
+#                      MULTILIB_* Variables as needed.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+  n_reuse = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "# Auto-generated Makefile Snip"
+	  print "# Generated by    : ./gcc/config/arc/genmultilib.awk"
+	  print "# Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print "# Used by         : tmake_file from Makefile and genmultilib"
+	  print ""
+	}
+    }
+
+  comment = 2;
+
+  print
+}
+
+/^$/ {
+  # The first empty line stops copy-pasting the GPL comments
+  # from this file to the generated file.
+
+  comment = 0
+}
+
+
+/^ARC_CPU/ {
+  name = $2
+  #  gsub ("\"", "", name)
+
+  if ($4 != "0")
+    {
+      arch = $3
+      if (arch == "6xx")
+	arch = 601
+
+      n = split ($4, cpu_flg, "|")
+
+      line = "mcpu." arch
+      for (i = 1; i <= n; i++)
+	{
+	  if (cpu_flg[i] == "FL_MPYOPT_0")
+	    line = line "/mmpy-option.0"
+	  else if (cpu_flg[i] == "FL_MPYOPT_1")
+	    line = line "/mmpy-option.1"
+	  else if (cpu_flg[i] == "FL_MPYOPT_2")
+	    line = line "/mmpy-option.2"
+	  else if (cpu_flg[i] == "FL_MPYOPT_3")
+	    line = line "/mmpy-option.3"
+	  else if (cpu_flg[i] == "FL_MPYOPT_4")
+	    line = line "/mmpy-option.4"
+	  else if (cpu_flg[i] == "FL_MPYOPT_5")
+	    line = line "/mmpy-option.5"
+	  else if (cpu_flg[i] == "FL_MPYOPT_6")
+	    line = line "/mmpy-option.6"
+	  else if (cpu_flg[i] == "FL_MPYOPT_7")
+	    line = line "/mmpy-option.7"
+	  else if (cpu_flg[i] == "FL_MPYOPT_8")
+	    line = line "/mmpy-option.8"
+	  else if (cpu_flg[i] == "FL_MPYOPT_9")
+	    line = line "/mmpy-option.9"
+	  else if (cpu_flg[i] == "FL_CD")
+	    line = line "/mcode-density"
+	  else if (cpu_flg[i] == "FL_BS")
+	    line = line "/mbarrel-shifter"
+	  else if (cpu_flg[i] == "FL_DIVREM")
+	    line = line "/mdiv-rem"
+	  else if (cpu_flg[i] == "FL_NORM" \
+		   || cpu_flg[i] == "FL_SWAP")
+	    line = line "/mnorm"
+	  else if (cpu_flg[i] == "FL_FPU_FPUS")
+	    line = line "/mfpu.fpus"
+	  else if (cpu_flg[i] == "FL_FPU_FPUDA")
+	    line = line "/mfpu.fpuda"
+	  else if (cpu_flg[i] == "FL_FPU_FPUD_ALL")
+	    line = line "/mfpu.fpud_all"
+	  else if (cpu_flg[i] == "FL_LL64")
+	    line = line "/mll64"
+	  else if (cpu_flg[i] == "FL_MUL64")
+	    line = line "/mmul64"
+	  else if (cpu_flg[i] == "FL_MUL32x16")
+	    line = line "/mmul32x16"
+	  else if (cpu_flg[i] == "FL_FPX_QUARK")
+	    line = line "/quark"
+	  else if (cpu_flg[i] == "FL_SPFP")
+	    line = line "/spfp"
+	  else if (cpu_flg[i] == "FL_DPFP")
+	    line = line "/dpfp"
+	  else
+	    {
+	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
+	      exit 1
+	    }
+	}
+      line = "mcpu." name "=" line
+      reuse[n_reuse] = line
+      n_reuse++
+    }
+
+  core = name
+  cores[n_cores] = core
+  n_cores++
+}
+
+##################################################################
+#
+# We gathered all the Information, now build/output the following:
+#
+#    awk Variable         target Variable          FORMAT
+#  -----------------------------------------------------------
+#    m_options     <->    MULTILIB_OPTIONS         Makefile
+#    m_dirnames    <->    MULTILIB_DIRNAMES           "
+#
+##################################################################
+
+END {
+  m_options    = "\nMULTILIB_OPTIONS = "
+  m_dirnames   = "\nMULTILIB_DIRNAMES ="
+  m_reuse      = "\nMULTILIB_REUSE ="
+
+  sep = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options  = m_options sep "mcpu=" cores[c]
+      m_dirnames = m_dirnames " " cores[c]
+      sep = "/"
+    }
+
+  sep = ""
+  for (c = 0; c < n_reuse; c++)
+    {
+      m_reuse = m_reuse sep reuse[c]
+      sep = "\nMULTILIB_REUSE +="
+    }
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+      # Intended Target: ./gcc/config/arc/t-multilib
+
+      print m_options
+      print m_dirnames
+      print m_reuse
+
+      ############################################################
+      # Legacy Aliases
+      ############################################################
+
+      print ""
+      print "# Aliases:"
+      print "MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mA6"
+      print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601"
+      print "MULTILIB_MATCHES += mcpu?arc700=mA7"
+      print "MULTILIB_MATCHES += mcpu?arc700=mARC700"
+    }
+}
diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk
new file mode 100644
index 0000000..24a93eb
--- /dev/null
+++ b/gcc/config/arc/genoptions.awk
@@ -0,0 +1,86 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "; Auto-generated Makefile Snip"
+	  print "; Generated by    : ./gcc/config/arc/genoptions.awk"
+	  print "; Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print ";"
+	}
+    }
+
+  comment = 2;
+
+  gsub ("^#", ";", $0)
+  print
+}
+
+/^$/ {
+    # The first empty line stops copy-pasting the GPL comments
+    # from this file to the generated file.
+    comment = 0
+}
+
+/^ARC_CPU/ {
+  name = $2
+  cores[n_cores] = name;
+  n_cores++
+}
+
+END {
+  m_option = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options = m_options "EnumValue\nEnum(processor_type) String(" \
+	cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n"
+    }
+
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+	print "\nEnum"
+	print "Name(processor_type) Type(enum processor_type)"
+	print "Known ARC CPUs (for use with the -mcpu= option):\n"
+	print m_options
+    }
+}
diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
index 4252e73..bdb1328 100644
--- a/gcc/config/arc/t-arc
+++ b/gcc/config/arc/t-arc
@@ -19,11 +19,30 @@
 
 TM_H += $(srcdir)/config/arc/arc-c.def
 
+driver-arc.o: $(srcdir)/config/arc/driver-arc.c \
+  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
 arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \
 $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arc/arc-c.c
 
+#Run `arc-cpus` if you changed something in arc-cpus.def
+
+.PHONY: arc-cpus
+
+arc-cpus: $(srcdir)/config/arc/t-multilib \
+	$(srcdir)/config/arc/arc-tables.opt
+
+$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk 	\
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
+$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
 # Local Variables:
 # mode: Makefile
 # End:
diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib
deleted file mode 100644
index c49a3fcc..0000000
--- a/gcc/config/arc/t-arc-newlib
+++ /dev/null
@@ -1,46 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm
-MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm
-#
-# Aliases:
-MULTILIB_MATCHES  = mcpu?ARC600=mcpu?arc600
-MULTILIB_MATCHES += mcpu?ARC600=mARC600
-MULTILIB_MATCHES += mcpu?ARC600=mA6
-MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
-MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
-MULTILIB_MATCHES += mcpu?ARC700=mA7
-MULTILIB_MATCHES += mcpu?ARC700=mARC700
-MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700
-MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem
-MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs
-MULTILIB_MATCHES += EL=mlittle-endian
-MULTILIB_MATCHES += EB=mbig-endian
-#
-# These don't make sense for the ARC700 default target:
-MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm*
-# And neither of the -mmul* options make sense without -mnorm:
-MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
-# Exclusions for ARC700
-MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16*
-# Exclusions for ARCv2EM
-MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16*
-# Exclusions for ARCv2HS
-MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm*
diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-arc-uClibc
deleted file mode 100644
index 11e81f1..0000000
--- a/gcc/config/arc/t-arc-uClibc
+++ /dev/null
@@ -1,20 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
new file mode 100644
index 0000000..1407bdf
--- /dev/null
+++ b/gcc/config/arc/t-multilib
@@ -0,0 +1,51 @@
+# Auto-generated Makefile Snip
+# Generated by    : ./gcc/config/arc/genmultilib.awk
+# Generated from  : ./gcc/config/arc/arc-cpu.def
+# Used by         : tmake_file from Makefile and genmultilib
+
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
+
+MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
+
+MULTILIB_REUSE =mcpu.arcem=mcpu.em/mmpy-option.2/mcode-density/mbarrel-shifter
+MULTILIB_REUSE +=mcpu.em4=mcpu.em/mcode-density
+MULTILIB_REUSE +=mcpu.em4_dmips=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter
+MULTILIB_REUSE +=mcpu.em4_fpus=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpus
+MULTILIB_REUSE +=mcpu.em4_fpuda=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpuda
+MULTILIB_REUSE +=mcpu.archs=mcpu.hs/mmpy-option.2/mdiv-rem/mll64
+MULTILIB_REUSE +=mcpu.hs34=mcpu.hs/mmpy-option.2
+MULTILIB_REUSE +=mcpu.hs38=mcpu.hs/mmpy-option.9/mdiv-rem/mll64
+MULTILIB_REUSE +=mcpu.hs38_linux=mcpu.hs/mmpy-option.9/mdiv-rem/mll64/mfpu.fpud_all
+MULTILIB_REUSE +=mcpu.arc600=mcpu.601/mbarrel-shifter
+MULTILIB_REUSE +=mcpu.arc600_norm=mcpu.601/mbarrel-shifter/mnorm
+MULTILIB_REUSE +=mcpu.arc600_mul64=mcpu.601/mbarrel-shifter/mnorm/mmul64
+MULTILIB_REUSE +=mcpu.arc600_mul32x16=mcpu.601/mbarrel-shifter/mnorm/mmul32x16
+MULTILIB_REUSE +=mcpu.arc601_norm=mcpu.601/mnorm
+MULTILIB_REUSE +=mcpu.arc601_mul64=mcpu.601/mnorm/mmul64
+MULTILIB_REUSE +=mcpu.arc601_mul32x16=mcpu.601/mnorm/mmul32x16
+
+# Aliases:
+MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
+MULTILIB_MATCHES += mcpu?arc600=mARC600
+MULTILIB_MATCHES += mcpu?arc600=mA6
+MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601
+MULTILIB_MATCHES += mcpu?arc700=mA7
+MULTILIB_MATCHES += mcpu?arc700=mARC700
diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc
new file mode 100644
index 0000000..11e81f1
--- /dev/null
+++ b/gcc/config/arc/t-uClibc
@@ -0,0 +1,20 @@
+# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
+
+# Copyright (C) 2007-2016 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+
+# You should have received a copy of the GNU General Public License along
+# with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 9e92133..66aa32f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13300,29 +13300,88 @@ values for @var{cpu} are
 @table @samp
 @opindex mA6
 @opindex mARC600
-@item ARC600
 @item arc600
 Compile for ARC600.  Aliases: @option{-mA6}, @option{-mARC600}.
 
-@item ARC601
 @item arc601
 @opindex mARC601
 Compile for ARC601.  Alias: @option{-mARC601}.
 
-@item ARC700
 @item arc700
 @opindex mA7
 @opindex mARC700
 Compile for ARC700.  Aliases: @option{-mA7}, @option{-mARC700}.
 This is the default when configured with @option{--with-cpu=arc700}@.
 
-@item ARCEM
 @item arcem
 Compile for ARC EM.
 
-@item ARCHS
 @item archs
 Compile for ARC HS.
+
+@item em
+@opindex em
+Compile for ARC EM cpu with no hardware extension.
+
+@item em4
+@opindex em4
+Compile for ARC EM4 cpu.
+
+@item em4_dmips
+@opindex em4_dmips
+Compile for ARC EM4 DMIPS cpu.
+
+@item em4_fpus
+@opindex em4_pus
+Compile for ARC EM4 DMIPS cpu with single precision floating point
+extension.
+
+@item em4_fpuda
+@opindex em4_fpuda
+Compile for ARC EM4 DMIPS cpu with single precision floating point and
+double assists instructions.
+
+@item hs
+@opindex hs
+Compile for ARC HS cpu with no hardware extension, except the atomic
+instructions.
+
+@item hs34
+@opindex hs34
+Compile for ARC HS34 cpu.
+
+@item hs38
+@opindex hs38
+Compile for ARC HS38 cpu.
+
+@item hs38_linux
+@opindex hs38_linux
+Compile for ARC HS38 cpu with all hardware extensions on.
+
+@item arc600_norm
+@opindex arc600_norm
+Compile for ARC 600 cpu with norm instruction enabled.
+
+@item arc600_mul32x16
+@opindex arc600_mul32x16
+Compile for ARC 600 cpu with norm and mul32x16 instructions enabled.
+
+@item arc600_mul64
+@opindex arc600_mul64
+Compile for ARC 600 cpu with norm and mul64 instructions enabled.
+
+@item arc601_norm
+@opindex arc601_norm
+Compile for ARC 601 cpu with norm instruction enabled.
+
+@item arc601_mul32x16
+@opindex arc601_mul32x16
+Compile for ARC 601 cpu with norm and mul32x16 instructions enabled.
+
+@item arc601_mul64
+@opindex arc601_mul64
+Compile for ARC 601 cpu with norm and mul64 instructions enabled.
+
 @end table
 
 @item -mdpfp
@@ -13349,7 +13408,8 @@ supported.  This is always enabled for @option{-mcpu=ARC700}.
 
 @item -mno-mpy
 @opindex mno-mpy
-Do not generate mpy instructions for ARC700.
+Do not generate mpy instructions for ARC700.  This instruction is
+deprecated.
 
 @item -mmul32x16
 @opindex mmul32x16
@@ -13556,12 +13616,14 @@ define preprocessor macro symbols.
 @item -mdsp-packa
 @opindex mdsp-packa
 Passed down to the assembler to enable the DSP Pack A extensions.
-Also sets the preprocessor symbol @code{__Xdsp_packa}.
+Also sets the preprocessor symbol @code{__Xdsp_packa}.  This option is
+deprecated.
 
 @item -mdvbf
 @opindex mdvbf
 Passed down to the assembler to enable the dual viterbi butterfly
-extension.  Also sets the preprocessor symbol @code{__Xdvbf}.
+extension.  Also sets the preprocessor symbol @code{__Xdvbf}.  This
+option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mlock
@@ -13573,19 +13635,19 @@ Conditional extension.  Also sets the preprocessor symbol
 @item -mmac-d16
 @opindex mmac-d16
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_d16}.
+@code{__Xxmac_d16}.  This option is deprecated.
 
 @item -mmac-24
 @opindex mmac-24
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_24}.
+@code{__Xxmac_24}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mrtsc
 @opindex mrtsc
 Passed down to the assembler to enable the 64-bit Time-Stamp Counter
 extension instruction.  Also sets the preprocessor symbol
-@code{__Xrtsc}.
+@code{__Xrtsc}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mswape
@@ -13598,7 +13660,7 @@ extension instruction.  Also sets the preprocessor symbol
 @opindex mtelephony
 Passed down to the assembler to enable dual and single operand
 instructions for telephony.  Also sets the preprocessor symbol
-@code{__Xtelephony}.
+@code{__Xtelephony}.  This option is deprecated.
 
 @item -mxy
 @opindex mxy
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 2/2] [ARC] Update target specific tests.
  2016-05-30 14:07 [PATCH 0/2] [ARC] Refurbish backend options Claudiu Zissulescu
  2016-05-30 14:19 ` [PATCH 1/2] [ARC] New option handling, refurbish multilib support Claudiu Zissulescu
@ 2016-05-30 14:21 ` Claudiu Zissulescu
  2016-11-15 15:23   ` Claudiu Zissulescu
  2016-11-16 15:58   ` Andrew Burgess
  2016-06-15  7:06 ` [PATCH 0/2] [ARC] Refurbish backend options Claudiu Zissulescu
  2 siblings, 2 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-05-30 14:21 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, gnu, Francois.Bedard

Update the ARC specific tests.

OK to apply?
Claudiu

gcc/
2016-05-26  Claudiu Zissulescu  <claziss@synopsys.com>

	* testsuite/gcc.target/arc/abitest.S: New file.
	* testsuite/gcc.target/arc/va_args-1.c: Likewise.
	* testsuite/gcc.target/arc/va_args-2.c: Likewise.
	* testsuite/gcc.target/arc/va_args-3.c: Likewise.
	* testsuite/gcc.target/arc/mcrc.c: Deleted.
	* testsuite/gcc.target/arc/mdsp-packa.c: Likewise.
	* testsuite/gcc.target/arc/mdvbf.c: Likewise.
	* testsuite/gcc.target/arc/mmac-24.c: Likewise.
	* testsuite/gcc.target/arc/mmac-d16.c: Likewise.
	* testsuite/gcc.target/arc/mno-crc.c: Likewise.
	* testsuite/gcc.target/arc/mno-dsp-packa.c: Likewise.
	* testsuite/gcc.target/arc/mno-dvbf.c: Likewise.
	* testsuite/gcc.target/arc/mno-mac-24.c: Likewise.
	* testsuite/gcc.target/arc/mno-mac-d16.c: Likewise.
	* testsuite/gcc.target/arc/mno-rtsc.c: Likewise.
	* testsuite/gcc.target/arc/mno-xy.c: Likewise.
	* testsuite/gcc.target/arc/mrtsc.c: Likewise.
	* testsuite/gcc.target/arc/arc.exp (check_effective_target_arcem):
	New function.
	(check_effective_target_arc700): Likewise.
	(check_effective_target_arc6xx): Likewise.
	(check_effective_target_arcmpy): Likewise.
	(check_effective_target_archs): Likewise.
	(check_effective_target_clmcpu): Likewise.
	* testsuite/gcc.target/arc/barrel-shifter-1.c: Changed.
	* testsuite/gcc.target/arc/builtin_simd.c: Test only for ARC700
	cpus.
	* testsuite/gcc.target/arc/cmem-1.c: Changed.
	* testsuite/gcc.target/arc/cmem-2.c: Likewise.
	* testsuite/gcc.target/arc/cmem-3.c: Likewise.
	* testsuite/gcc.target/arc/cmem-4.c: Likewise.
	* testsuite/gcc.target/arc/cmem-5.c: Likewise.
	* testsuite/gcc.target/arc/cmem-6.c: Likewise.
	* testsuite/gcc.target/arc/cmem-7.c: Likewise.
	* testsuite/gcc.target/arc/interrupt-1.c: Test for RTIE as well.
	* testsuite/gcc.target/arc/interrupt-2.c: Skip it for ARCv2 cores.
	* testsuite/gcc.target/arc/interrupt-3.c: Match also ARCv2
	warnings.
	* testsuite/gcc.target/arc/jump-around-jump.c: Update options.
	* testsuite/gcc.target/arc/mARC601.c: Changed.
	* testsuite/gcc.target/arc/mcpu-arc600.c: Changed.
	* testsuite/gcc.target/arc/mcpu-arc601.c: Changed.
	* testsuite/gcc.target/arc/mcpu-arc700.c: Changed.
	* testsuite/gcc.target/arc/mdpfp.c: Skip for ARCv2 cores.
	* testsuite/gcc.target/arc/movb-1.c: Changed.
	* testsuite/gcc.target/arc/movb-2.c: Likewise.
	* testsuite/gcc.target/arc/movb-3.c: Likewise.
	* testsuite/gcc.target/arc/movb-4.c: Likewise.
	* testsuite/gcc.target/arc/movb-5.c: Likewise.
	* testsuite/gcc.target/arc/movb_cl-1.c: Likewise.
	* testsuite/gcc.target/arc/movb_cl-2.c: Likewise.
	* testsuite/gcc.target/arc/movbi_cl-1.c: Likewise.
	* testsuite/gcc.target/arc/movh_cl-1.c: Likewise.
	* testsuite/gcc.target/arc/mspfp.c: Skip for ARC HS cores.
	* testsuite/gcc.target/arc/mul64.c: Enable it only for ARC600.
	* testsuite/gcc.target/arc/mulsi3_highpart-1.c: Scan for ARCv2
	instructions.
	* testsuite/gcc.target/arc/mulsi3_highpart-2.c: Skip it for ARCv1
	cores.
	* testsuite/gcc.target/arc/no-dpfp-lrsr.c: Skip it for ARC HS.
	* testsuite/gcc.target/arc/trsub.c: Only for ARC EM cores.
	* testsuite/gcc.target/arc/builtin_simdarc.c: Changed.
	* testsuite/gcc.target/arc/extzv-1.c: Likewise.
	* testsuite/gcc.target/arc/insv-1.c: Likewise.
	* testsuite/gcc.target/arc/insv-2.c: Likewise.
	* testsuite/gcc.target/arc/mA6.c: Likewise.
	* testsuite/gcc.target/arc/mA7.c: Likewise.
	* testsuite/gcc.target/arc/mARC600.c: Likewise.
	* testsuite/gcc.target/arc/mARC700.c: Likewise.
	* testsuite/gcc.target/arc/mcpu-arc600.c: Likewise.
	* testsuite/gcc.target/arc/mcpu-arc700.c: Likewise.
	* testsuite/gcc.target/arc/movl-1.c: Likewise.
	* testsuite/gcc.target/arc/nps400-1.c: Likewise.
	* testsuite/gcc.target/arc/trsub.c: Likewise.
---
 gcc/testsuite/gcc.target/arc/abitest.S           | 31 +++++++++++
 gcc/testsuite/gcc.target/arc/arc.exp             | 66 +++++++++++++++++++++++-
 gcc/testsuite/gcc.target/arc/barrel-shifter-1.c  |  2 +-
 gcc/testsuite/gcc.target/arc/builtin_simd.c      |  1 +
 gcc/testsuite/gcc.target/arc/builtin_simdarc.c   |  1 +
 gcc/testsuite/gcc.target/arc/cmem-1.c            |  1 +
 gcc/testsuite/gcc.target/arc/cmem-2.c            |  1 +
 gcc/testsuite/gcc.target/arc/cmem-3.c            |  1 +
 gcc/testsuite/gcc.target/arc/cmem-4.c            |  1 +
 gcc/testsuite/gcc.target/arc/cmem-5.c            |  1 +
 gcc/testsuite/gcc.target/arc/cmem-6.c            |  1 +
 gcc/testsuite/gcc.target/arc/cmem-7.c            |  1 +
 gcc/testsuite/gcc.target/arc/extzv-1.c           |  1 +
 gcc/testsuite/gcc.target/arc/insv-1.c            |  1 +
 gcc/testsuite/gcc.target/arc/insv-2.c            |  1 +
 gcc/testsuite/gcc.target/arc/interrupt-1.c       |  7 ++-
 gcc/testsuite/gcc.target/arc/interrupt-2.c       |  1 +
 gcc/testsuite/gcc.target/arc/interrupt-3.c       |  2 +-
 gcc/testsuite/gcc.target/arc/jump-around-jump.c  |  2 +-
 gcc/testsuite/gcc.target/arc/mA6.c               |  1 +
 gcc/testsuite/gcc.target/arc/mA7.c               |  1 +
 gcc/testsuite/gcc.target/arc/mARC600.c           |  1 +
 gcc/testsuite/gcc.target/arc/mARC601.c           |  3 +-
 gcc/testsuite/gcc.target/arc/mARC700.c           |  1 +
 gcc/testsuite/gcc.target/arc/mcpu-arc600.c       |  3 +-
 gcc/testsuite/gcc.target/arc/mcpu-arc601.c       |  5 +-
 gcc/testsuite/gcc.target/arc/mcpu-arc700.c       |  3 +-
 gcc/testsuite/gcc.target/arc/mcrc.c              |  8 ---
 gcc/testsuite/gcc.target/arc/mdpfp.c             |  1 +
 gcc/testsuite/gcc.target/arc/mdsp-packa.c        |  9 ----
 gcc/testsuite/gcc.target/arc/mdvbf.c             |  9 ----
 gcc/testsuite/gcc.target/arc/mmac-24.c           |  8 ---
 gcc/testsuite/gcc.target/arc/mmac-d16.c          |  9 ----
 gcc/testsuite/gcc.target/arc/mno-crc.c           | 11 ----
 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c     | 11 ----
 gcc/testsuite/gcc.target/arc/mno-dvbf.c          | 11 ----
 gcc/testsuite/gcc.target/arc/mno-mac-24.c        | 11 ----
 gcc/testsuite/gcc.target/arc/mno-mac-d16.c       | 11 ----
 gcc/testsuite/gcc.target/arc/mno-rtsc.c          | 11 ----
 gcc/testsuite/gcc.target/arc/mno-xy.c            | 10 ----
 gcc/testsuite/gcc.target/arc/movb-1.c            |  1 +
 gcc/testsuite/gcc.target/arc/movb-2.c            |  1 +
 gcc/testsuite/gcc.target/arc/movb-3.c            |  1 +
 gcc/testsuite/gcc.target/arc/movb-4.c            |  1 +
 gcc/testsuite/gcc.target/arc/movb-5.c            |  1 +
 gcc/testsuite/gcc.target/arc/movb_cl-1.c         |  1 +
 gcc/testsuite/gcc.target/arc/movb_cl-2.c         |  1 +
 gcc/testsuite/gcc.target/arc/movbi_cl-1.c        |  1 +
 gcc/testsuite/gcc.target/arc/movh_cl-1.c         |  1 +
 gcc/testsuite/gcc.target/arc/movl-1.c            |  1 +
 gcc/testsuite/gcc.target/arc/mrtsc.c             |  8 ---
 gcc/testsuite/gcc.target/arc/mspfp.c             |  1 +
 gcc/testsuite/gcc.target/arc/mul64.c             |  3 +-
 gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c |  5 +-
 gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c |  4 +-
 gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c      |  1 +
 gcc/testsuite/gcc.target/arc/nps400-1.c          |  1 +
 gcc/testsuite/gcc.target/arc/trsub.c             |  1 +
 gcc/testsuite/gcc.target/arc/va_args-1.c         | 16 ++++++
 gcc/testsuite/gcc.target/arc/va_args-2.c         | 14 +++++
 gcc/testsuite/gcc.target/arc/va_args-3.c         | 15 ++++++
 61 files changed, 198 insertions(+), 142 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/abitest.S
 delete mode 100644 gcc/testsuite/gcc.target/arc/mcrc.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mdsp-packa.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mdvbf.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-24.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-d16.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-crc.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dvbf.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-24.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-d16.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-rtsc.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mno-xy.c
 delete mode 100644 gcc/testsuite/gcc.target/arc/mrtsc.c
 create mode 100644 gcc/testsuite/gcc.target/arc/va_args-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/va_args-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/va_args-3.c

diff --git a/gcc/testsuite/gcc.target/arc/abitest.S b/gcc/testsuite/gcc.target/arc/abitest.S
new file mode 100644
index 0000000..7be935b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/abitest.S
@@ -0,0 +1,31 @@
+/* { dg-do assemble } */
+#ifndef ENTRY
+#define ENTRY(nm)               \
+        .text `                 \
+        .align 4 `              \
+        .globl nm `             \
+        .type nm,@function `    \
+nm:
+#endif
+
+#ifndef END
+#define END(name)       .size name,.-name
+#endif
+
+ENTRY(tsyscall)
+ENTRY(clone)
+	add	r0,r0,r1
+	add	r0,r0,r2
+	add	r0,r0,r3
+	add	r0,r0,r4
+	add	r0,r0,r5
+	j_s.d	[blink]
+	add	r0,r0,r6
+END(tsyscall)
+END(clone)
+
+ENTRY(abidi)
+	add.f r0,r1,1
+        j_s.d [blink]
+        adc r1,r2,0
+END(abidi)
diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp
index fae2ece7..3b7d100 100644
--- a/gcc/testsuite/gcc.target/arc/arc.exp
+++ b/gcc/testsuite/gcc.target/arc/arc.exp
@@ -4,12 +4,12 @@
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
@@ -24,6 +24,68 @@ if ![istarget arc*-*-*] then {
 # Load support procs.
 load_lib gcc-dg.exp
 
+# Return 1 if this is a compiler supporting ARCv2 EM as default processor
+proc check_effective_target_arcem { } {
+    return [check_no_compiler_messages arcem assembly {
+	#if !defined (__ARCEM__)
+	#error No ARC EM
+	#endif
+    }]
+}
+
+# Return 1 if we compile for ARC700
+proc check_effective_target_arc700 { } {
+    return [check_no_compiler_messages arc700 assembly {
+	#if !defined (__ARC700__)
+	#error No ARC 700
+	#endif
+    }]
+}
+
+# Return 1 if we compile for ARC6xx
+proc check_effective_target_arc6xx { } {
+    return [check_no_compiler_messages arc6xx assembly {
+	#if !defined (__ARC600__) && !defined (__ARC601__)
+	#error No ARC 6xx
+	#endif
+    }]
+}
+
+# Return 1 if we have mpy
+proc check_effective_target_arcmpy { } {
+    return [check_no_compiler_messages arcmpy assembly {
+	#if !defined (__ARC_MPY__)
+	#error No MPY
+	#endif
+    }]
+}
+
+# Return 1 if this is a compiler supporting ARC HS as default processor
+proc check_effective_target_archs { } {
+    return [check_no_compiler_messages archs assembly {
+	#if !defined (__ARCHS__)
+	#error No ARC HS
+	#endif
+    }]
+}
+
+proc check_cl { flags } {
+    return [check_no_compiler_messages check_$flags assembly {
+	#if !defined (__arc__)
+	#error Extra mcpu options
+	#endif
+    } "$flags"]
+}
+
+# Return 1 if there are no extra mcpu options given via command line
+proc check_effective_target_clmcpu { } {
+    if { [check_cl "-mcpu=arc700"]
+	 && [check_cl "-mcpu=arcem" ] } {
+	return 1
+    }
+    return 0
+}
+
 # If a testcase doesn't have special options, use these.
 global DEFAULT_CFLAGS
 if ![info exists DEFAULT_CFLAGS] then {
diff --git a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
index a0eb6d7..5cfb282 100644
--- a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
+++ b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mcpu=ARC601 -mbarrel-shifter" } */
+/* { dg-options "-O2 -mbarrel-shifter" } */
 int i;
 
 int f (void)
diff --git a/gcc/testsuite/gcc.target/arc/builtin_simd.c b/gcc/testsuite/gcc.target/arc/builtin_simd.c
index fff27a4..6b02521 100644
--- a/gcc/testsuite/gcc.target/arc/builtin_simd.c
+++ b/gcc/testsuite/gcc.target/arc/builtin_simd.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-O2 -Werror-implicit-function-declaration -mARC700 -msimd" } */
 
 #define STEST1(name, rettype, op1)		\
diff --git a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
index 68aae40..0cfe2ad 100644
--- a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
+++ b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=archs -O2 -Werror-implicit-function-declaration -mmpy-option=9" } */
 
 #define STEST(name, rettype, op1type, op2type)	\
diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c b/gcc/testsuite/gcc.target/arc/cmem-1.c
index 7f36afb..8ed5dcf 100644
--- a/gcc/testsuite/gcc.target/arc/cmem-1.c
+++ b/gcc/testsuite/gcc.target/arc/cmem-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mcmem" } */
 
 #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c b/gcc/testsuite/gcc.target/arc/cmem-2.c
index a3d7c130..39bfb28 100644
--- a/gcc/testsuite/gcc.target/arc/cmem-2.c
+++ b/gcc/testsuite/gcc.target/arc/cmem-2.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mcmem" } */
 
 #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c b/gcc/testsuite/gcc.target/arc/cmem-3.c
index dee73b5..109084f 100644
--- a/gcc/testsuite/gcc.target/arc/cmem-3.c
+++ b/gcc/testsuite/gcc.target/arc/cmem-3.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mcmem" } */
 
 #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c b/gcc/testsuite/gcc.target/arc/cmem-4.c
index 1da6bce..4ac8a22 100644
--- a/gcc/testsuite/gcc.target/arc/cmem-4.c
+++ b/gcc/testsuite/gcc.target/arc/cmem-4.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mcmem" } */
 
 #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c b/gcc/testsuite/gcc.target/arc/cmem-5.c
index ad6904f..451218b 100644
--- a/gcc/testsuite/gcc.target/arc/cmem-5.c
+++ b/gcc/testsuite/gcc.target/arc/cmem-5.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mcmem" } */
 
 #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c b/gcc/testsuite/gcc.target/arc/cmem-6.c
index 24bc39b..0ed0608 100644
--- a/gcc/testsuite/gcc.target/arc/cmem-6.c
+++ b/gcc/testsuite/gcc.target/arc/cmem-6.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mcmem" } */
 
 #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c b/gcc/testsuite/gcc.target/arc/cmem-7.c
index 72ee7bd..0267327 100644
--- a/gcc/testsuite/gcc.target/arc/cmem-7.c
+++ b/gcc/testsuite/gcc.target/arc/cmem-7.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mcmem" } */
 
 struct some_struct
diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c b/gcc/testsuite/gcc.target/arc/extzv-1.c
index 242f522..1e5533a7 100644
--- a/gcc/testsuite/gcc.target/arc/extzv-1.c
+++ b/gcc/testsuite/gcc.target/arc/extzv-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct foo { unsigned a: 3, b: 5, c: 24; };
diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c b/gcc/testsuite/gcc.target/arc/insv-1.c
index 75d47e9..29e4188 100644
--- a/gcc/testsuite/gcc.target/arc/insv-1.c
+++ b/gcc/testsuite/gcc.target/arc/insv-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 /* ??? Irrespective of insn set, generated code for this is a mess.  */
diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c b/gcc/testsuite/gcc.target/arc/insv-2.c
index 1652551..620acec 100644
--- a/gcc/testsuite/gcc.target/arc/insv-2.c
+++ b/gcc/testsuite/gcc.target/arc/insv-2.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct foo { unsigned a: 3, b: 8, c: 21; } bar;
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-1.c b/gcc/testsuite/gcc.target/arc/interrupt-1.c
index 7051457..8a2002b 100644
--- a/gcc/testsuite/gcc.target/arc/interrupt-1.c
+++ b/gcc/testsuite/gcc.target/arc/interrupt-1.c
@@ -1,5 +1,10 @@
+#if defined (__ARCHS__) || defined (__ARCEM__)
+void __attribute__ ((interrupt("ilink")))
+#else
 void __attribute__ ((interrupt("ilink1")))
+#endif
 handler1 (void)
 {
 }
-/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 } } */
+/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 { target { arc700 || arc6xx } } } } */
+/* { dg-final { scan-assembler-times "rtie" 1 { target { arcem || archs } } } } */
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-2.c b/gcc/testsuite/gcc.target/arc/interrupt-2.c
index ee8593b..285ebd5 100644
--- a/gcc/testsuite/gcc.target/arc/interrupt-2.c
+++ b/gcc/testsuite/gcc.target/arc/interrupt-2.c
@@ -1,3 +1,4 @@
+/* { dg-skip-if "ilink2 is not an ARCv2 register" { archs || arcem } } */
 void __attribute__ ((interrupt("ilink2")))
 handler1 (void)
 {
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-3.c b/gcc/testsuite/gcc.target/arc/interrupt-3.c
index fa598d6..b0cad88 100644
--- a/gcc/testsuite/gcc.target/arc/interrupt-3.c
+++ b/gcc/testsuite/gcc.target/arc/interrupt-3.c
@@ -5,7 +5,7 @@ handler0 (void)
 
 void __attribute__ ((interrupt("you load too")))
 handler1 (void)
-{ /* { dg-warning "is not \"ilink1\" or \"ilink2\"" } */
+{ /* { dg-warning "is not \"ilink" } */
 }
 
 void __attribute__ ((interrupt(42)))
diff --git a/gcc/testsuite/gcc.target/arc/jump-around-jump.c b/gcc/testsuite/gcc.target/arc/jump-around-jump.c
index 338c667..2fd3fb6 100644
--- a/gcc/testsuite/gcc.target/arc/jump-around-jump.c
+++ b/gcc/testsuite/gcc.target/arc/jump-around-jump.c
@@ -1,5 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-Os -mlock -mswape -mrtsc -fno-reorder-blocks" } */
+/* { dg-options "-Os -mlock -mswape -fno-reorder-blocks" } */
 
 /* This caused an ICE in arc_ifcvt when the 1->3 state change was not
    implemented for TYPE_UNCOND_BRANCH in arc_ccfsm_post_advance.  */
diff --git a/gcc/testsuite/gcc.target/arc/mA6.c b/gcc/testsuite/gcc.target/arc/mA6.c
index 2e15a86..c4eeb6f 100644
--- a/gcc/testsuite/gcc.target/arc/mA6.c
+++ b/gcc/testsuite/gcc.target/arc/mA6.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mA6" } */
 
 /* { dg-final { scan-assembler ".cpu ARC600" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mA7.c b/gcc/testsuite/gcc.target/arc/mA7.c
index c4430f4..a3c6f82 100644
--- a/gcc/testsuite/gcc.target/arc/mA7.c
+++ b/gcc/testsuite/gcc.target/arc/mA7.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mA7" } */
 
 /* { dg-final { scan-assembler ".cpu ARC700" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mARC600.c b/gcc/testsuite/gcc.target/arc/mARC600.c
index 20e086a..6a80457 100644
--- a/gcc/testsuite/gcc.target/arc/mARC600.c
+++ b/gcc/testsuite/gcc.target/arc/mARC600.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mARC600" } */
 
 /* { dg-final { scan-assembler ".cpu ARC600" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mARC601.c b/gcc/testsuite/gcc.target/arc/mARC601.c
index 1d30da4..d238661 100644
--- a/gcc/testsuite/gcc.target/arc/mARC601.c
+++ b/gcc/testsuite/gcc.target/arc/mARC601.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mARC601" } */
 
-/* { dg-final { scan-assembler ".cpu ARC601" } } */
+/* { dg-final { scan-assembler ".cpu ARC60.*" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mARC700.c b/gcc/testsuite/gcc.target/arc/mARC700.c
index 43e9baa..d34583f 100644
--- a/gcc/testsuite/gcc.target/arc/mARC700.c
+++ b/gcc/testsuite/gcc.target/arc/mARC700.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mARC700" } */
 
 /* { dg-final { scan-assembler ".cpu ARC700" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
index 4c915fd..bd1dc95 100644
--- a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
+++ b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mcpu=ARC600" } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
+/* { dg-options "-mcpu=arc600" } */
 
 /* { dg-final { scan-assembler ".cpu ARC600" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
index 7c93c9d..8ef046e 100644
--- a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
+++ b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mcpu=ARC601" } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
+/* { dg-options "-mcpu=arc601" } */
 
-/* { dg-final { scan-assembler ".cpu ARC601" } } */
+/* { dg-final { scan-assembler ".cpu ARC60.*" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
index c805a5a..25bb400 100644
--- a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
+++ b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
-/* { dg-options "-mcpu=ARC700" } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
+/* { dg-options "-mcpu=arc700" } */
 
 /* { dg-final { scan-assembler ".cpu ARC700" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mcrc.c b/gcc/testsuite/gcc.target/arc/mcrc.c
deleted file mode 100644
index a449bdd..0000000
--- a/gcc/testsuite/gcc.target/arc/mcrc.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/* { dg-options "-mcrc" } */
-/* { dg-do assemble } */
-
-int f (int i)
-{
-  __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mdpfp.c b/gcc/testsuite/gcc.target/arc/mdpfp.c
index 4bbc905..aa6bdfa 100644
--- a/gcc/testsuite/gcc.target/arc/mdpfp.c
+++ b/gcc/testsuite/gcc.target/arc/mdpfp.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */
 /* { dg-options "-O2 -mdpfp" } */
 
 double i;
diff --git a/gcc/testsuite/gcc.target/arc/mdsp-packa.c b/gcc/testsuite/gcc.target/arc/mdsp-packa.c
deleted file mode 100644
index f013a6d..0000000
--- a/gcc/testsuite/gcc.target/arc/mdsp-packa.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mdsp-packa" } */
-/* { dg-do assemble } */
-
-int f (int i)
-{
-  __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mdvbf.c b/gcc/testsuite/gcc.target/arc/mdvbf.c
deleted file mode 100644
index e2e545e..0000000
--- a/gcc/testsuite/gcc.target/arc/mdvbf.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mdvbf" } */
-/* { dg-do assemble } */
-
-int f (int i)
-{
-  __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mmac-24.c b/gcc/testsuite/gcc.target/arc/mmac-24.c
deleted file mode 100644
index 89da0b1..0000000
--- a/gcc/testsuite/gcc.target/arc/mmac-24.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/* { dg-options "-mmac-24" } */
-/* { dg-do assemble } */
-
-int f (int i)
-{
-  __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mmac-d16.c b/gcc/testsuite/gcc.target/arc/mmac-d16.c
deleted file mode 100644
index 0570011..0000000
--- a/gcc/testsuite/gcc.target/arc/mmac-d16.c
+++ /dev/null
@@ -1,9 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mmac-d16" } */
-/* { dg-do assemble } */
-
-int f (int i)
-{
-  __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mno-crc.c b/gcc/testsuite/gcc.target/arc/mno-crc.c
deleted file mode 100644
index 70ab9c1..0000000
--- a/gcc/testsuite/gcc.target/arc/mno-crc.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mno-crc" } */
-/* Would also like to assemble and check that we get the expected
-   "Error: bad instruction" assembler messages, but at the moment our
-   testharness can't do that.  */
-
-int f (int i)
-{
-  __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c b/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
deleted file mode 100644
index eb21522..0000000
--- a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mno-dsp-packa" } */
-/* Would also like to assemble and check that we get the expected
-   "Error: bad instruction" assembler messages, but at the moment our
-   testharness can't do that.  */
-
-int f (int i)
-{
-  __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mno-dvbf.c b/gcc/testsuite/gcc.target/arc/mno-dvbf.c
deleted file mode 100644
index ea96d98..0000000
--- a/gcc/testsuite/gcc.target/arc/mno-dvbf.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mno-dvbf" } */
-/* Would also like to assemble and check that we get the expected
-   "Error: bad instruction" assembler messages, but at the moment our
-   testharness can't do that.  */
-
-int f (int i)
-{
-  __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-24.c b/gcc/testsuite/gcc.target/arc/mno-mac-24.c
deleted file mode 100644
index b483957..0000000
--- a/gcc/testsuite/gcc.target/arc/mno-mac-24.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mno-mac-24" } */
-/* Would also like to assemble and check that we get the expected
-   "Error: bad instruction" assembler messages, but at the moment our
-   testharness can't do that.  */
-
-int f (int i)
-{
-  __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c b/gcc/testsuite/gcc.target/arc/mno-mac-d16.c
deleted file mode 100644
index 68a20f4..0000000
--- a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mno-mac-d16" } */
-/* Would also like to assemble and check that we get the expected
-   "Error: bad instruction" assembler messages, but at the moment our
-   testharness can't do that.  */
-
-int f (int i)
-{
-  __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mno-rtsc.c b/gcc/testsuite/gcc.target/arc/mno-rtsc.c
deleted file mode 100644
index d74a60e..0000000
--- a/gcc/testsuite/gcc.target/arc/mno-rtsc.c
+++ /dev/null
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mno-rtsc" } */
-/* Would also like to assemble and check that we get the expected
-   "Error: bad instruction" assembler messages, but at the moment our
-   testharness can't do that.  */
-
-int f (int i)
-{
-  __asm__("rtsc %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mno-xy.c b/gcc/testsuite/gcc.target/arc/mno-xy.c
deleted file mode 100644
index e378b3f..0000000
--- a/gcc/testsuite/gcc.target/arc/mno-xy.c
+++ /dev/null
@@ -1,10 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-mno-xy" } */
-/* Would also like to assemble and check that we get the expected
-   "Error: bad instruction" assembler messages, but at the moment our
-   testharness can't do that.  */
-
-void f (int i)
-{
-  __asm__("add x0_u0, x0_u0, %0" : :  "r" (i));
-}
diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
index 65d4ba4..965fd66 100644
--- a/gcc/testsuite/gcc.target/arc/movb-1.c
+++ b/gcc/testsuite/gcc.target/arc/movb-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct { unsigned a: 5, b: 8, c: 19; } foo;
diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
index 1ba9976..9bd6d41 100644
--- a/gcc/testsuite/gcc.target/arc/movb-2.c
+++ b/gcc/testsuite/gcc.target/arc/movb-2.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct { unsigned a: 23, b: 9; } foo;
diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c b/gcc/testsuite/gcc.target/arc/movb-3.c
index 0895154..34145d6 100644
--- a/gcc/testsuite/gcc.target/arc/movb-3.c
+++ b/gcc/testsuite/gcc.target/arc/movb-3.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct { int a: 23, b: 9; } foo;
diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c b/gcc/testsuite/gcc.target/arc/movb-4.c
index 89bf2c2..83efad6 100644
--- a/gcc/testsuite/gcc.target/arc/movb-4.c
+++ b/gcc/testsuite/gcc.target/arc/movb-4.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct { int a: 13, b: 19; } foo;
diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
index 9dbe8a1..0bcdd1c 100644
--- a/gcc/testsuite/gcc.target/arc/movb-5.c
+++ b/gcc/testsuite/gcc.target/arc/movb-5.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct { int a: 23, b: 9; } foo;
diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
index 402250c..977a0c2 100644
--- a/gcc/testsuite/gcc.target/arc/movb_cl-1.c
+++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 int
diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
index d2e5a94..4a1484a 100644
--- a/gcc/testsuite/gcc.target/arc/movb_cl-2.c
+++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 extern void g (void);
diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
index 3c457db..a86d06f 100644
--- a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
+++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 int
diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
index 220cd9d..13c0f34 100644
--- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
+++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 struct thing
diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c b/gcc/testsuite/gcc.target/arc/movl-1.c
index f1f0130..c44ca8d 100644
--- a/gcc/testsuite/gcc.target/arc/movl-1.c
+++ b/gcc/testsuite/gcc.target/arc/movl-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
 
 int
diff --git a/gcc/testsuite/gcc.target/arc/mrtsc.c b/gcc/testsuite/gcc.target/arc/mrtsc.c
deleted file mode 100644
index 15cb939..0000000
--- a/gcc/testsuite/gcc.target/arc/mrtsc.c
+++ /dev/null
@@ -1,8 +0,0 @@
-/* { dg-options "-mrtsc" } */
-/* { dg-do assemble } */
-
-int f (int i)
-{
-  __asm__("rtsc %1, %1" : "=r"(i) : "r"(i));
-  return i;
-}
diff --git a/gcc/testsuite/gcc.target/arc/mspfp.c b/gcc/testsuite/gcc.target/arc/mspfp.c
index 0e41ff8..19cb978 100644
--- a/gcc/testsuite/gcc.target/arc/mspfp.c
+++ b/gcc/testsuite/gcc.target/arc/mspfp.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "FPX is not an ARC HS extension" { archs } } */
 /* { dg-options "-O2 -mspfp" } */
 
 float i;
diff --git a/gcc/testsuite/gcc.target/arc/mul64.c b/gcc/testsuite/gcc.target/arc/mul64.c
index 3678b27..680dfd8 100644
--- a/gcc/testsuite/gcc.target/arc/mul64.c
+++ b/gcc/testsuite/gcc.target/arc/mul64.c
@@ -1,5 +1,6 @@
 /* { dg-do compile } */
-/* { dg-options "-O2 -mcpu=ARC600 -mmul64" } */
+/* { dg-skip-if "MUL64 is ARC600 extension" { ! { arc6xx } } } */
+/* { dg-options "-O2 -mcpu=arc600 -mmul64" } */
 #include <stdint.h>
 
 int64_t i;
diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
index 398ecfe..fd48f65 100644
--- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
+++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
@@ -1,5 +1,5 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mARC700 --save-temps" } */
+/* { dg-options "-O2" } */
 
 #include <stdlib.h>
 
@@ -25,4 +25,5 @@ main (void)
   return 0;
 }
 
-/* { dg-final { scan-assembler "mpyhu\[ \t\]" } } */
+/* { dg-final { scan-assembler "mpyhu\[ \t\]" { target { arc700 } } } } */
+/* { dg-final { scan-assembler "mpy.u\[ \t\]" { target { { ! { arc700 } } && arcmpy } } } } */
diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
index ccc74e7..287d96d 100644
--- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
+++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
@@ -1,5 +1,7 @@
 /* { dg-do run } */
-/* { dg-options "-O2 -mARC700 --save-temps -mno-mpy" } */
+/* { dg-skip-if "ARC700 always has mpy option on" { arc700 } } */
+/* { dg-skip-if "ARC600 doesn't have mpy instruction" { arc6xx } } */
+/* { dg-options "-O2 --save-temps -mmpy-option=0" } */
 
 #include <stdlib.h>
 
diff --git a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
index e4e23e4..61f07b5 100644
--- a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
+++ b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */
 /* { dg-options "-O2 -mdpfp -mno-dpfp-lrsr" } */
 
 double i;
diff --git a/gcc/testsuite/gcc.target/arc/nps400-1.c b/gcc/testsuite/gcc.target/arc/nps400-1.c
index f3d6271..504aad7 100644
--- a/gcc/testsuite/gcc.target/arc/nps400-1.c
+++ b/gcc/testsuite/gcc.target/arc/nps400-1.c
@@ -1,4 +1,5 @@
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mcpu=nps400 -mq-class -mbitops -munaligned-access -mcmem -O2 -fno-strict-aliasing" } */
 
 enum npsdp_mem_space_type {
diff --git a/gcc/testsuite/gcc.target/arc/trsub.c b/gcc/testsuite/gcc.target/arc/trsub.c
index 031935f..8ea5711 100644
--- a/gcc/testsuite/gcc.target/arc/trsub.c
+++ b/gcc/testsuite/gcc.target/arc/trsub.c
@@ -1,6 +1,7 @@
 /* Tests if we generate rsub instructions when compiling using
    floating point assist instructions.  */
 /* { dg-do compile } */
+/* { dg-skip-if "" { ! { clmcpu } } } */
 /* { dg-options "-mfpu=fpuda -mcpu=arcem" } */
 
 double foo (double a)
diff --git a/gcc/testsuite/gcc.target/arc/va_args-1.c b/gcc/testsuite/gcc.target/arc/va_args-1.c
new file mode 100644
index 0000000..4a35d12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/va_args-1.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-sources "abitest.S" } */
+
+extern long tsyscall (long int sysnum, ...);
+
+int main (void)
+{
+  long a;
+
+  a = tsyscall (1, 2, 3, 4, 5, 6, 7);
+
+  if (a != 28)
+    return 1;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arc/va_args-2.c b/gcc/testsuite/gcc.target/arc/va_args-2.c
new file mode 100644
index 0000000..1a49251
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/va_args-2.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-sources "abitest.S" } */
+
+extern int clone (int (*fn)(void *), void *child_stack,
+		  int flags, void *arg, ...);
+
+int main (void)
+{
+  int a = clone ((void *) 1, (void *)2, 3, (void *) 4, 5, 6, 7);
+  if (a != 28)
+    return 1;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arc/va_args-3.c b/gcc/testsuite/gcc.target/arc/va_args-3.c
new file mode 100644
index 0000000..45624c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/va_args-3.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-sources "abitest.S" } */
+
+extern long long abidi (int a, ...);
+
+int main (void)
+{
+  long long a = 1;
+  a = abidi (10, a);
+
+  if (a != 2)
+    return 1;
+  return 0;
+}
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 0/2] [ARC] Refurbish backend options
  2016-05-30 14:07 [PATCH 0/2] [ARC] Refurbish backend options Claudiu Zissulescu
  2016-05-30 14:19 ` [PATCH 1/2] [ARC] New option handling, refurbish multilib support Claudiu Zissulescu
  2016-05-30 14:21 ` [PATCH 2/2] [ARC] Update target specific tests Claudiu Zissulescu
@ 2016-06-15  7:06 ` Claudiu Zissulescu
  2 siblings, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-06-15  7:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: gnu, Francois.Bedard

PING

> -----Original Message-----
> From: Claudiu Zissulescu
> Sent: Monday, May 30, 2016 2:33 PM
> To: gcc-patches@gcc.gnu.org
> Cc: Claudiu Zissulescu <claziss@synopsys.com>; gnu@amylaar.uk;
> Francois.Bedard@synopsys.com
> Subject: [PATCH 0/2] [ARC] Refurbish backend options
> 
> This series of patches redefines the way how we handle the options
> within the ARC backend. Firstly, a number of options got deprecated as
> they were directed to control the assembler behavior, assembler which
> got overhaul and ignores the options in question. Secondly, we remove
> the capitalized cpu names accepted by mcpu option. Finally, we
> introduced new cpu options, based on the Synopsys predefined CPU
> templates to make easier the translation from hardware CPU template to
> gcc options. Those new cpu options are handled by a number of scripts
> which seamlessly generates gcc options, multilib variants, and
> checking the allowed hardware extensions against gcc command line
> options.
> 
> Please find two patches, one which is refurbishing the ARC options,
> and the second one which updates the ARC specific tests.
> 
> Claudiu Zissulescu (2):
>   New option handling, refurbish multilib support.
>   Update target specific tests.
> 
>  gcc/common/config/arc/arc-common.c               | 162 ++++++++++++------
>  gcc/config.gcc                                   |  47 +++---
>  gcc/config/arc/arc-arch.h                        | 120 +++++++++++++
>  gcc/config/arc/arc-arches.def                    |  35 ++++
>  gcc/config/arc/arc-c.def                         |   4 +
>  gcc/config/arc/arc-cpus.def                      |  47 ++++++
>  gcc/config/arc/arc-options.def                   |  69 ++++++++
>  gcc/config/arc/arc-opts.h                        |  47 +++++-
>  gcc/config/arc/arc-protos.h                      |   1 -
>  gcc/config/arc/arc-tables.opt                    |  90 ++++++++++
>  gcc/config/arc/arc.c                             | 186 +++++++++++----------
>  gcc/config/arc/arc.h                             |  91 +++++-----
>  gcc/config/arc/arc.md                            |   5 -
>  gcc/config/arc/arc.opt                           | 109 ++++--------
>  gcc/config/arc/driver-arc.c                      |  80 +++++++++
>  gcc/config/arc/genmultilib.awk                   | 204 +++++++++++++++++++++++
>  gcc/config/arc/genoptions.awk                    |  86 ++++++++++
>  gcc/config/arc/t-arc                             |  19 +++
>  gcc/config/arc/t-arc-newlib                      |  46 -----
>  gcc/config/arc/t-arc-uClibc                      |  20 ---
>  gcc/config/arc/t-multilib                        |  51 ++++++
>  gcc/config/arc/t-uClibc                          |  20 +++
>  gcc/doc/invoke.texi                              |  86 ++++++++--
>  gcc/testsuite/gcc.target/arc/abitest.S           |  31 ++++
>  gcc/testsuite/gcc.target/arc/arc.exp             |  66 +++++++-
>  gcc/testsuite/gcc.target/arc/barrel-shifter-1.c  |   2 +-
>  gcc/testsuite/gcc.target/arc/builtin_simd.c      |   1 +
>  gcc/testsuite/gcc.target/arc/builtin_simdarc.c   |   1 +
>  gcc/testsuite/gcc.target/arc/cmem-1.c            |   1 +
>  gcc/testsuite/gcc.target/arc/cmem-2.c            |   1 +
>  gcc/testsuite/gcc.target/arc/cmem-3.c            |   1 +
>  gcc/testsuite/gcc.target/arc/cmem-4.c            |   1 +
>  gcc/testsuite/gcc.target/arc/cmem-5.c            |   1 +
>  gcc/testsuite/gcc.target/arc/cmem-6.c            |   1 +
>  gcc/testsuite/gcc.target/arc/cmem-7.c            |   1 +
>  gcc/testsuite/gcc.target/arc/extzv-1.c           |   1 +
>  gcc/testsuite/gcc.target/arc/insv-1.c            |   1 +
>  gcc/testsuite/gcc.target/arc/insv-2.c            |   1 +
>  gcc/testsuite/gcc.target/arc/interrupt-1.c       |   7 +-
>  gcc/testsuite/gcc.target/arc/interrupt-2.c       |   1 +
>  gcc/testsuite/gcc.target/arc/interrupt-3.c       |   2 +-
>  gcc/testsuite/gcc.target/arc/jump-around-jump.c  |   2 +-
>  gcc/testsuite/gcc.target/arc/mA6.c               |   1 +
>  gcc/testsuite/gcc.target/arc/mA7.c               |   1 +
>  gcc/testsuite/gcc.target/arc/mARC600.c           |   1 +
>  gcc/testsuite/gcc.target/arc/mARC601.c           |   3 +-
>  gcc/testsuite/gcc.target/arc/mARC700.c           |   1 +
>  gcc/testsuite/gcc.target/arc/mcpu-arc600.c       |   3 +-
>  gcc/testsuite/gcc.target/arc/mcpu-arc601.c       |   5 +-
>  gcc/testsuite/gcc.target/arc/mcpu-arc700.c       |   3 +-
>  gcc/testsuite/gcc.target/arc/mcrc.c              |   8 -
>  gcc/testsuite/gcc.target/arc/mdpfp.c             |   1 +
>  gcc/testsuite/gcc.target/arc/mdsp-packa.c        |   9 -
>  gcc/testsuite/gcc.target/arc/mdvbf.c             |   9 -
>  gcc/testsuite/gcc.target/arc/mmac-24.c           |   8 -
>  gcc/testsuite/gcc.target/arc/mmac-d16.c          |   9 -
>  gcc/testsuite/gcc.target/arc/mno-crc.c           |  11 --
>  gcc/testsuite/gcc.target/arc/mno-dsp-packa.c     |  11 --
>  gcc/testsuite/gcc.target/arc/mno-dvbf.c          |  11 --
>  gcc/testsuite/gcc.target/arc/mno-mac-24.c        |  11 --
>  gcc/testsuite/gcc.target/arc/mno-mac-d16.c       |  11 --
>  gcc/testsuite/gcc.target/arc/mno-rtsc.c          |  11 --
>  gcc/testsuite/gcc.target/arc/mno-xy.c            |  10 --
>  gcc/testsuite/gcc.target/arc/movb-1.c            |   1 +
>  gcc/testsuite/gcc.target/arc/movb-2.c            |   1 +
>  gcc/testsuite/gcc.target/arc/movb-3.c            |   1 +
>  gcc/testsuite/gcc.target/arc/movb-4.c            |   1 +
>  gcc/testsuite/gcc.target/arc/movb-5.c            |   1 +
>  gcc/testsuite/gcc.target/arc/movb_cl-1.c         |   1 +
>  gcc/testsuite/gcc.target/arc/movb_cl-2.c         |   1 +
>  gcc/testsuite/gcc.target/arc/movbi_cl-1.c        |   1 +
>  gcc/testsuite/gcc.target/arc/movh_cl-1.c         |   1 +
>  gcc/testsuite/gcc.target/arc/movl-1.c            |   1 +
>  gcc/testsuite/gcc.target/arc/mrtsc.c             |   8 -
>  gcc/testsuite/gcc.target/arc/mspfp.c             |   1 +
>  gcc/testsuite/gcc.target/arc/mul64.c             |   3 +-
>  gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c |   5 +-
>  gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c |   4 +-
>  gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c      |   1 +
>  gcc/testsuite/gcc.target/arc/nps400-1.c          |   1 +
>  gcc/testsuite/gcc.target/arc/trsub.c             |   1 +
>  gcc/testsuite/gcc.target/arc/va_args-1.c         |  16 ++
>  gcc/testsuite/gcc.target/arc/va_args-2.c         |  14 ++
>  gcc/testsuite/gcc.target/arc/va_args-3.c         |  15 ++
>  84 files changed, 1447 insertions(+), 518 deletions(-)
>  create mode 100644 gcc/config/arc/arc-arch.h
>  create mode 100644 gcc/config/arc/arc-arches.def
>  create mode 100644 gcc/config/arc/arc-cpus.def
>  create mode 100644 gcc/config/arc/arc-options.def
>  create mode 100644 gcc/config/arc/arc-tables.opt
>  create mode 100644 gcc/config/arc/driver-arc.c
>  create mode 100644 gcc/config/arc/genmultilib.awk
>  create mode 100644 gcc/config/arc/genoptions.awk
>  delete mode 100644 gcc/config/arc/t-arc-newlib
>  delete mode 100644 gcc/config/arc/t-arc-uClibc
>  create mode 100644 gcc/config/arc/t-multilib
>  create mode 100644 gcc/config/arc/t-uClibc
>  create mode 100644 gcc/testsuite/gcc.target/arc/abitest.S
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mcrc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mdsp-packa.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mdvbf.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-24.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-d16.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-crc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dvbf.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-24.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-d16.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-rtsc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-xy.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mrtsc.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-1.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-2.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-3.c
> 
> --
> 1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-05-30 14:19 ` [PATCH 1/2] [ARC] New option handling, refurbish multilib support Claudiu Zissulescu
@ 2016-10-10 13:28   ` Claudiu Zissulescu
  2016-10-12 20:02     ` Andrew Burgess
  0 siblings, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-10-10 13:28 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

Hi Andrew,

This is updated patch of the original sent to mailing list some while ago.

What is new:
     - Do not use MULTILIB_REUSE as its semantic changed, and the old one was causing issues while building.
     - Update invoke.texi documentation adding nps400 option to mcpu.

This patch is important as it changes the way how we handle CPU
variations and multilib support. It will be great if you can include
this patch on your review list before any other one.

Thanks,
Claudiu

gcc/
2016-05-09  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-arch.h: New file.
	* config/arc/arc-arches.def: Likewise.
	* config/arc/arc-cpus.def: Likewise.
	* config/arc/arc-options.def: Likewise.
	* config/arc/t-multilib: Likewise.
	* config/arc/genmultilib.awk: Likewise.
	* config/arc/genoptions.awk: Likewise.
	* config/arc/arc-tables.opt: Likewise.
	* config/arc/driver-arc.c: Likewise.
	* common/config/arc/arc-common.c (arc_handle_option): Trace
	toggled options.
	* config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra
	options; check for supported cpu against arc-cpus.def file.
	(arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define
	TARGET_CPU_BUILD macro; add driver-arc.o as an extra object.
	* config/arc/arc-c.def: Add emacs local variables.
	* config/arc/arc-opts.h (processor_type): Use arc-cpus.def file.
	(FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA)
	(FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL)
	(FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines.
	(DEFAULT_arc_fpu_build): Define.
	(DEFAULT_arc_mpy_option): Define.
	* config/arc/arc-protos.h (arc_init): Delete.
	* config/arc/arc.c (arc_cpu_name): New variable.
	(arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs)
	(arc_arc700, arc_arc600, arc_arc601): New variable.
	(arc_init): Add static; remove selection of default tune value,
	cleanup obsolete error messages.
	(arc_override_options): Make use of .def files for selecting the
	right cpu and option configurations.
	* config/arc/arc.h (stdbool.h): Include.
	(TARGET_CPU_DEFAULT): Define.
	(CPP_SPEC): Remove mcpu=NPS400 handling.
	(arc_cpu_to_as): Declare.
	(EXTRA_SPEC_FUNCTIONS): Define.
	(OPTION_DEFAULT_SPECS): Likewise.
	(ASM_DEFAULT): Remove.
	(ASM_SPEC): Use arc_cpu_to_as.
	(DRIVER_SELF_SPECS): Remove deprecated options.
	(arc_arc700, arc_arc600, arc_arc601, arc_arcem, arc_archs):
	Declare.
	(TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM)
	(TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_arc*
	variables.
	(MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT.
	* config/arc/arc.md (attr_cpu): Remove.
	* config/arc/arc.opt (arc_mpy_option): Make it target variable.
	(mno-mpy): Deprecate.
	(mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM)
	(mcpu=ARCHS): Remove.
	(mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc):
	Deprecate.
	(mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove.
	(arc_fpu): Use new defines.
	(arc_seen_options): New target variable.
	* config/arc/t-arc (driver-arc.o): New target.
	(arc-cpus, t-multilib, arc-tables.opt): Likewise.
	* config/arc/t-arc-newlib: Delete.
	* config/arc/t-arc-uClibc: Renamed to t-uClibc.
	* doc/invoke.texi (ARC): Update arc options.
---
 gcc/common/config/arc/arc-common.c | 162 ++++++++++++++++++++---------
 gcc/config.gcc                     |  47 +++++----
 gcc/config/arc/arc-arch.h          | 120 ++++++++++++++++++++++
 gcc/config/arc/arc-arches.def      |  35 +++++++
 gcc/config/arc/arc-c.def           |   4 +
 gcc/config/arc/arc-cpus.def        |  47 +++++++++
 gcc/config/arc/arc-options.def     |  69 +++++++++++++
 gcc/config/arc/arc-opts.h          |  47 +++++++--
 gcc/config/arc/arc-protos.h        |   1 -
 gcc/config/arc/arc-tables.opt      |  90 ++++++++++++++++
 gcc/config/arc/arc.c               | 186 ++++++++++++++++++---------------
 gcc/config/arc/arc.h               |  91 ++++++++---------
 gcc/config/arc/arc.md              |   5 -
 gcc/config/arc/arc.opt             | 109 ++++++--------------
 gcc/config/arc/driver-arc.c        |  80 +++++++++++++++
 gcc/config/arc/genmultilib.awk     | 203 +++++++++++++++++++++++++++++++++++++
 gcc/config/arc/genoptions.awk      |  86 ++++++++++++++++
 gcc/config/arc/t-arc               |  19 ++++
 gcc/config/arc/t-arc-newlib        |  46 ---------
 gcc/config/arc/t-arc-uClibc        |  20 ----
 gcc/config/arc/t-multilib          |  34 +++++++
 gcc/config/arc/t-uClibc            |  20 ++++
 gcc/doc/invoke.texi                |  90 +++++++++++++---
 23 files changed, 1235 insertions(+), 376 deletions(-)
 create mode 100644 gcc/config/arc/arc-arch.h
 create mode 100644 gcc/config/arc/arc-arches.def
 create mode 100644 gcc/config/arc/arc-cpus.def
 create mode 100644 gcc/config/arc/arc-options.def
 create mode 100644 gcc/config/arc/arc-tables.opt
 create mode 100644 gcc/config/arc/driver-arc.c
 create mode 100644 gcc/config/arc/genmultilib.awk
 create mode 100644 gcc/config/arc/genoptions.awk
 delete mode 100644 gcc/config/arc/t-arc-newlib
 delete mode 100644 gcc/config/arc/t-arc-uClibc
 create mode 100644 gcc/config/arc/t-multilib
 create mode 100644 gcc/config/arc/t-uClibc

diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index 5b687fb..2898860 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -2,6 +2,7 @@
    Copyright (C) 1994-2016 Free Software Foundation, Inc.
    Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
 		on behalf of Synopsys Inc.
+		Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
 
 This file is part of GCC.
 
@@ -61,17 +62,19 @@ static const struct default_options arc_option_optimization_table[] =
 
 /*  Process options.  */
 static bool
-arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
+arc_handle_option (struct gcc_options *opts,
+		   struct gcc_options *opts_set ATTRIBUTE_UNUSED,
 		   const struct cl_decoded_option *decoded,
 		   location_t loc)
 {
   size_t code = decoded->opt_index;
   int value = decoded->value;
   const char *arg = decoded->arg;
+  static int mcpu_seen = PROCESSOR_NONE;
+  char *p;
 
   switch (code)
     {
-      static int mcpu_seen = PROCESSOR_NONE;
     case OPT_mcpu_:
       /* N.B., at this point arc_cpu has already been set to its new value by
 	 our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless.  */
@@ -79,71 +82,130 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
       if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
 	warning_at (loc, 0, "multiple -mcpu= options specified.");
       mcpu_seen = value;
+      break;
+
+    case OPT_mmpy_option_:
+      p = ASTRDUP (arg);
 
-      switch (value)
+      if (!strcmp (p, "0")
+	  || !strcmp (p, "none"))
+	opts->x_arc_mpy_option = 0;
+      else if (!strcmp (p, "1")
+	  || !strcmp (p, "w"))
 	{
-	case PROCESSOR_NPS400:
-	  if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) )
-	    opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1;
-	  /* Fall through */
-	case PROCESSOR_ARC600:
-	case PROCESSOR_ARC700:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARC601:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARCHS:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags |= MASK_CODE_DENSITY;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags |= MASK_NORM_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags |= MASK_SWAP_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags |= MASK_DIVREM;	  /* Default: on.  */
-	  break;
-
-	case PROCESSOR_ARCEM:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags &= ~MASK_CODE_DENSITY;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags &= ~MASK_NORM_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags &= ~MASK_SWAP_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags &= ~MASK_DIVREM;	  /* Default: off.  */
-	  break;
-	default:
-	  gcc_unreachable ();
+	  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);
+
       break;
 
-    case OPT_mmpy_option_:
-      if (value < 0 || value > 9)
-	error_at (loc, "bad value %qs for -mmpy-option switch", arg);
+    case OPT_mcode_density:
+      opts->x_arc_seen_options |= MASK_CODE_DENSITY;
+      break;
+
+    case OPT_mdiv_rem:
+      opts->x_arc_seen_options |= MASK_DIVREM;
+      break;
+
+    case OPT_mnorm:
+      opts->x_arc_seen_options |= MASK_NORM_SET;
+      break;
+
+    case OPT_matomic:
+      opts->x_arc_seen_options |= MASK_ATOMIC;
+      break;
+
+    case OPT_mll64:
+      opts->x_arc_seen_options |= MASK_LL64;
+      break;
+
+    case OPT_mbarrel_shifter:
+      opts->x_arc_seen_options |= MASK_BARREL_SHIFTER;
+      break;
+
+    case OPT_mswap:
+      opts->x_arc_seen_options |= MASK_SWAP_SET;
+      break;
+
+    case OPT_mmul64:
+      opts->x_arc_seen_options |= MASK_MUL64_SET;
+      break;
+
+    case OPT_mmul32x16:
+      opts->x_arc_seen_options |= MASK_MULMAC_32BY16_SET;
+      break;
+
+    case OPT_mEA:
+      opts->x_arc_seen_options |= MASK_EA_SET;
+      break;
+
+    case OPT_mspfp:
+    case OPT_mspfp_compact:
+    case OPT_mspfp_fast:
+      opts->x_arc_seen_options |= MASK_SPFP_COMPACT_SET;
+      break;
+
+    case OPT_mdpfp:
+    case OPT_mdpfp_compact:
+    case OPT_mdpfp_fast:
+      opts->x_arc_seen_options |= MASK_DPFP_COMPACT_SET;
+      break;
+
+    case OPT_margonaut:
+      opts->x_arc_seen_options |= MASK_ARGONAUT_SET;
+      break;
+
+    case OPT_msimd:
+      opts->x_arc_seen_options |= MASK_SIMD_SET;
+      break;
+
+    default:
       break;
     }
 
   return true;
 }
 
+#undef  TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
+
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
 #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
-#define TARGET_HANDLE_OPTION arc_handle_option
 
 #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
 
-/* We default to ARC700, which has the barrel shifter enabled.  */
-#define TARGET_DEFAULT_TARGET_FLAGS \
-  (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET)
 
+#undef  TARGET_HANDLE_OPTION
+#define TARGET_HANDLE_OPTION arc_handle_option
 
 #include "common/common-target-def.h"
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 8fd07c5..50dca89 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -318,6 +318,7 @@ arc*-*-*)
 	cpu_type=arc
 	c_target_objs="arc-c.o"
 	cxx_target_objs="arc-c.o"
+	extra_options="${extra_options} arc/arc-tables.opt"
 	;;
 arm*-*-*)
 	cpu_type=arm
@@ -991,13 +992,12 @@ alpha*-dec-*vms*)
 	;;
 arc*-*-elf*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
-	tmake_file="arc/t-arc-newlib arc/t-arc"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
+	tmake_file="arc/t-multilib arc/t-arc"
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -1014,15 +1014,14 @@ arc*-*-elf*)
 	;;
 arc*-*-linux-uclibc*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
-	tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc"
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
+	tmake_file="${tmake_file} arc/t-uClibc arc/t-arc"
 	tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0"
 	tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -3605,15 +3604,19 @@ case "${target}" in
 		done
 		;;
 
-	arc*-*-*) # was:	arc*-*-linux-uclibc)
+	arc*-*-*)
 		supported_defaults="cpu"
-		case $with_cpu in
-		  arc600|arc601|arc700)
-			;;
-		  *) echo "Unknown cpu type"
-			exit 1
-			;;
-		esac
+
+		if [ x"$with_cpu" = x ] \
+		    || grep "^ARC_CPU ($with_cpu," \
+		       ${srcdir}/config/arc/arc-cpus.def \
+		       > /dev/null; then
+		 # Ok
+		 true
+		else
+		 echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
+		 exit 1
+		fi
 		;;
 
 	arm*-*-*)
diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
new file mode 100644
index 0000000..7994543
--- /dev/null
+++ b/gcc/config/arc/arc-arch.h
@@ -0,0 +1,120 @@
+/* Definitions of types that are used to store ARC architecture and
+   device information.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu (claziss@synopsys.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ARC_ARCH_H
+#define GCC_ARC_ARCH_H
+
+#ifndef IN_LIBGCC2
+/* Architecture selection types.  */
+
+enum cpu_flags
+  {
+#define ARC_OPT(NAME, CODE, MASK, DOC)	    NAME = CODE,
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE,
+#include "arc-options.def"
+#undef ARC_OPT
+#undef ARC_OPTX
+    FL_END
+  };
+
+
+/* ARC architecture variants.  */
+
+enum base_architecture
+  {
+    BASE_ARCH_NONE,
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)  BASE_ARCH_##ARCH,
+#include "arc-arches.def"
+#undef ARC_ARCH
+    BASE_ARCH_END
+  };
+
+
+/* Tune variants.  Needs to match the attr_tune enum.  */
+
+enum arc_tune_attr
+  {
+    ARC_TUNE_NONE,
+    ARC_TUNE_ARC600,
+    ARC_TUNE_ARC700_4_2_STD,
+    ARC_TUNE_ARC700_4_2_XMAC
+  };
+
+/* CPU specific properties.  */
+
+typedef struct
+{
+  /* CPU name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* Specific flags.  */
+  const unsigned long long flags;
+
+  /* Tune value.  */
+  enum arc_tune_attr tune;
+} arc_cpu_t;
+
+
+/* Architecture specific propoerties.  */
+
+typedef struct
+{
+  /* Architecture name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* All allowed flags for this architecture.  */
+  const unsigned long long flags;
+
+  /* Default flags for this architecture.  It is a subset of
+     FLAGS.  */
+  const unsigned long long dflags;
+} arc_arch_t;
+
+
+
+const arc_arch_t arc_arch_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, 0},
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)	\
+    {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS},
+#include "arc-arches.def"
+#undef ARC_ARCH
+    {NULL, BASE_ARCH_END, 0, 0}
+  };
+
+const arc_cpu_t arc_cpu_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE},
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
+    {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE},
+#include "arc-cpus.def"
+#undef ARC_CPU
+    {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE}
+  };
+
+#endif
+#endif /* GCC_ARC_ARCH_H */
diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
new file mode 100644
index 0000000..bd76124
--- /dev/null
+++ b/gcc/config/arc/arc-arches.def
@@ -0,0 +1,35 @@
+/* ARC ARCH architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
+	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
+	  | FL_SIMD | FL_FPUDA, 0)
+ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
+	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
+	  | FL_FPUS | FL_FPUD,						\
+	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
+ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
+	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
+ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
+	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
+	  FL_BS | FL_NORM | FL_SWAP)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
index 065e973..4cfd7b6 100644
--- a/gcc/config/arc/arc-c.def
+++ b/gcc/config/arc/arc-c.def
@@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__",     TARGET_EM)
 ARC_C_DEF ("__HS__",     TARGET_HS)
 ARC_C_DEF ("__Xnorm",    TARGET_NORM)
 ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
new file mode 100644
index 0000000..381507c
--- /dev/null
+++ b/gcc/config/arc/arc-cpus.def
@@ -0,0 +1,47 @@
+/* ARC CPU architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+ARC_CPU (em,	    em, 0, NONE)
+ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
+ARC_CPU (em4,	    em, FL_CD, NONE)
+ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
+ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
+ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
+
+ARC_CPU (hs,	     hs, 0, NONE)
+ARC_CPU (archs,	     hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs34,	     hs, FL_MPYOPT_2, NONE)
+ARC_CPU (hs38,	     hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE)
+
+ARC_CPU (arc600,	  6xx, FL_BS, ARC600)
+ARC_CPU (arc600_norm,	  6xx, FL_BS|FL_NORM, ARC600)
+ARC_CPU (arc600_mul64,	  6xx, FL_BS|FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600)
+ARC_CPU (arc601,	  6xx, 0, ARC600)
+ARC_CPU (arc601_norm,	  6xx, FL_NORM, ARC600)
+ARC_CPU (arc601_mul64,	  6xx, FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600)
+
+ARC_CPU (arc700, 700, 0, ARC700_4_2_STD)
+ARC_CPU (nps400, 700, 0, ARC700_4_2_STD)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
new file mode 100644
index 0000000..083719a
--- /dev/null
+++ b/gcc/config/arc/arc-options.def
@@ -0,0 +1,69 @@
+/* ARC options.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
+ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
+ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
+
+ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
+ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
+ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
+ARC_OPT (FL_SWAP,     (1ULL << 7), MASK_SWAP_SET,	   "swap")
+ARC_OPT (FL_MUL64,    (1ULL << 8), MASK_MUL64_SET,	   "mul64")
+ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16")
+
+ARC_OPT (FL_EA,	      (1ULL << 11), MASK_EA_SET,	   "extended arithmetics")
+ARC_OPT (FL_SPFP,     (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX")
+ARC_OPT (FL_DPFP,     (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX")
+ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET,	   "argonaut")
+ARC_OPT (FL_SIMD,     (1ULL << 15), MASK_SIMD_SET,	   "simd")
+
+ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w")
+ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1")
+ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2")
+ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3")
+ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4")
+ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5")
+ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy")
+ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd")
+ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw")
+
+ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option")
+ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option")
+
+ARC_OPTX (FL_FPU_FPUS,	    (1ULL << 26), arc_fpu_build, FPU_FPUS,	"mfpu=fpus")
+ARC_OPTX (FL_FPU_FPUS_DIV,  (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV,	"mfpu=fpus_div")
+ARC_OPTX (FL_FPU_FPUS_FMA,  (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA,	"mfpu=fpus_fma")
+ARC_OPTX (FL_FPU_FPUS_ALL,  (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL,	"mfpu=fpus_all")
+ARC_OPTX (FL_FPU_FPUDA,	    (1ULL << 30), arc_fpu_build, FPU_FPUDA,	"mfpu=fpuda")
+ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div")
+ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma")
+ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all")
+ARC_OPTX (FL_FPU_FPUD,	    (1ULL << 34), arc_fpu_build, FPU_FPUD,	"mfpu=fpud")
+ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV,	"mfpu=fpud_div")
+ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA,	"mfpu=fpud_fma")
+ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL,	"mfpu=fpud_all")
+
+ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
+ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
+ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
index cbd7898..81446b4 100644
--- a/gcc/config/arc/arc-opts.h
+++ b/gcc/config/arc/arc-opts.h
@@ -18,15 +18,16 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef ARC_OPTS_H
+#define ARC_OPTS_H
+
 enum processor_type
 {
-  PROCESSOR_NONE,
-  PROCESSOR_ARC600,
-  PROCESSOR_ARC601,
-  PROCESSOR_ARC700,
-  PROCESSOR_NPS400,
-  PROCESSOR_ARCEM,
-  PROCESSOR_ARCHS
+  PROCESSOR_NONE = 0,
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)  PROCESSOR_##NAME,
+#include "arc-cpus.def"
+#undef ARC_CPU
+  PROCESSOR_generic
 };
 
 /* Single precision floating point.  */
@@ -48,3 +49,35 @@ enum processor_type
 /* Double precision floating point assist operations.  */
 #define FPX_DP    0x0100
 
+/* fpus option combi.  */
+#define FPU_FPUS  (FPU_SP | FPU_SC)
+/* fpud option combi.  */
+#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+/* fpuda option combi.  */
+#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
+/* fpuda_div option combi.  */
+#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+/* fpuda_fma option combi.  */
+#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+/* fpuda_all option combi.  */
+#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+/* fpus_div option combi.  */
+#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
+/* fpus_fma option combi.  */
+#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
+/* fpus_all option combi.  */
+#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+/* fpud_div option combi.  */
+#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
+/* fpud_fma option combi.  */
+#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
+/* fpud_all option combi.  */
+#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+
+/* Default FPU option value.  */
+#define DEFAULT_arc_fpu_build 0x10000000
+
+/* Default MPY option value.  */
+#define DEFAULT_arc_mpy_option -1
+
+#endif /* ARC_OPTS_H */
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index ad5d4d3..d1266b4 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
 #endif /* TREE_CODE */
 
 
-extern void arc_init (void);
 extern unsigned int arc_compute_frame_size (int);
 extern bool arc_ccfsm_branch_deleted_p (void);
 extern void arc_ccfsm_record_branch_deleted (void);
diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
new file mode 100644
index 0000000..0e7c50c
--- /dev/null
+++ b/gcc/config/arc/arc-tables.opt
@@ -0,0 +1,90 @@
+; Auto-generated Makefile Snip
+; Generated by    : ./gcc/config/arc/genoptions.awk
+; Generated from  : ./gcc/config/arc/arc-cpu.def
+;
+; Copyright (C) 2016 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+Enum
+Name(processor_type) Type(enum processor_type)
+Known ARC CPUs (for use with the -mcpu= option):
+
+EnumValue
+Enum(processor_type) String(em) Value(PROCESSOR_em)
+
+EnumValue
+Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
+
+EnumValue
+Enum(processor_type) String(em4) Value(PROCESSOR_em4)
+
+EnumValue
+Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips)
+
+EnumValue
+Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
+
+EnumValue
+Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
+
+EnumValue
+Enum(processor_type) String(hs) Value(PROCESSOR_hs)
+
+EnumValue
+Enum(processor_type) String(archs) Value(PROCESSOR_archs)
+
+EnumValue
+Enum(processor_type) String(hs34) Value(PROCESSOR_hs34)
+
+EnumValue
+Enum(processor_type) String(hs38) Value(PROCESSOR_hs38)
+
+EnumValue
+Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux)
+
+EnumValue
+Enum(processor_type) String(arc600) Value(PROCESSOR_arc600)
+
+EnumValue
+Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm)
+
+EnumValue
+Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64)
+
+EnumValue
+Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc601) Value(PROCESSOR_arc601)
+
+EnumValue
+Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm)
+
+EnumValue
+Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64)
+
+EnumValue
+Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc700) Value(PROCESSOR_arc700)
+
+EnumValue
+Enum(processor_type) String(nps400) Value(PROCESSOR_nps400)
+
+
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 5e8d6b4..cfb3531 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -64,7 +64,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 
 /* Which cpu we're compiling for (ARC600, ARC601, ARC700).  */
-static const char *arc_cpu_string = "";
+static char arc_cpu_name[10] = "";
+static const char *arc_cpu_string = arc_cpu_name;
 
 /* ??? Loads can handle any constant, stores can only handle small ones.  */
 /* OTOH, LIMMs cost extra, so their usefulness is limited.  */
@@ -241,6 +242,16 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
 						enum by_pieces_operation op,
 						bool);
 
+static const arc_cpu_t *arc_selected_cpu;
+static const arc_arch_t *arc_selected_arch;
+
+/* Global var which sets the current compilation architecture.  */
+bool arc_arcem = false;
+bool arc_archs = false;
+bool arc_arc700 = false;
+bool arc_arc600 = false;
+bool arc_arc601 = false;
+
 /* Implements target hook vector_mode_supported_p.  */
 
 static bool
@@ -668,47 +679,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
 
 /* Called by OVERRIDE_OPTIONS to initialize various things.  */
 
-void
+static void
 arc_init (void)
 {
-  enum attr_tune tune_dflt = TUNE_NONE;
-
-  switch (arc_cpu)
-    {
-    case PROCESSOR_ARC600:
-      arc_cpu_string = "ARC600";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC601:
-      arc_cpu_string = "ARC601";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC700:
-      arc_cpu_string = "ARC700";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_NPS400:
-      arc_cpu_string = "NPS400";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_ARCEM:
-      arc_cpu_string = "EM";
-      break;
-
-    case PROCESSOR_ARCHS:
-      arc_cpu_string = "HS";
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  if (arc_tune == TUNE_NONE)
-    arc_tune = tune_dflt;
   /* Note: arc_multcost is only used in rtx_cost if speed is true.  */
   if (arc_multcost < 0)
     switch (arc_tune)
@@ -739,18 +712,10 @@ arc_init (void)
 	break;
       }
 
-  /* Support mul64 generation only for ARC600.  */
-  if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul64 not supported for ARC700 or ARCv2");
-
   /* MPY instructions valid only for ARC700 or ARCv2.  */
   if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
       error ("-mno-mpy supported only for ARC700 or ARCv2");
 
-  /* mul/mac instructions only for ARC600.  */
-  if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul32x16 supported only for ARC600 or ARC601");
-
   if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
       error ("-mno-dpfp-lrsr supported only with -mdpfp");
 
@@ -763,23 +728,11 @@ arc_init (void)
   if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
     error ("-mspfp_fast not available on ARC600 or ARC601");
 
-  /* FPX-3. No FPX extensions on pre-ARC600 cores.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
-    error ("FPX extensions not available on pre-ARC600 cores");
-
-  /* FPX-4.  No FPX extensions mixed with FPU extensions for ARC HS
-     cpus.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && TARGET_HARD_FLOAT
-      && TARGET_HS)
+  /* FPX-4.  No FPX extensions mixed with FPU extensions.  */
+  if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
+      && TARGET_HARD_FLOAT)
     error ("No FPX/FPU mixing allowed");
 
-  /* Only selected multiplier configurations are available for HS.  */
-  if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
-		    || (arc_mpy_option == 1)))
-    error ("This multiplier configuration is not available for HS cores");
-
   /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic.  */
   if (flag_pic && TARGET_ARC600_FAMILY)
     {
@@ -789,26 +742,6 @@ arc_init (void)
       flag_pic = 0;
     }
 
-  if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS))
-    error ("-matomic is only supported for ARC700 or ARC HS cores");
-
-  /* ll64 ops only available for HS.  */
-  if (TARGET_LL64 && !TARGET_HS)
-    error ("-mll64 is only supported for ARC HS cores");
-
-  /* FPU support only for V2.  */
-  if (TARGET_HARD_FLOAT)
-    {
-      if (TARGET_EM
-	  && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
-	error ("FPU double precision options are available for ARC HS only");
-      if (TARGET_HS && (arc_fpu_build & FPX_DP))
-	error ("FPU double precision assist "
-	       "options are not available for ARC HS");
-      if (!TARGET_HS && !TARGET_EM)
-	error ("FPU options are available for ARCv2 architecture only");
-    }
-
   arc_init_reg_tables ();
 
   /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
@@ -853,7 +786,92 @@ static void
 arc_override_options (void)
 {
   if (arc_cpu == PROCESSOR_NONE)
-    arc_cpu = PROCESSOR_ARC700;
+    arc_cpu = TARGET_CPU_DEFAULT;
+
+  /* Set the default cpu options.  */
+  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
+  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
+
+  /* Set the architectures.  */
+  switch (arc_selected_arch->arch)
+    {
+    case BASE_ARCH_em:
+      arc_arcem = true;
+      arc_cpu_string = "EM";
+      break;
+    case BASE_ARCH_hs:
+      arc_archs = true;
+      arc_cpu_string = "HS";
+      break;
+    case BASE_ARCH_700:
+      arc_arc700 = true;
+      arc_cpu_string = "ARC700";
+      break;
+    case BASE_ARCH_6xx:
+      arc_cpu_string = "ARC600";
+      if (arc_selected_cpu->flags & FL_BS)
+	arc_arc600 = true;
+      else
+	arc_arc601 = true;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
+     specific flags are set in arc-common.c.  The architecture forces
+     the default hardware configurations in, regardless what command
+     line options are saying.  The CPU optional hw options can be
+     turned on or off.  */
+#define ARC_OPT(NAME, CODE, MASK, DOC)		\
+  do {						\
+    if ((arc_selected_cpu->flags & CODE)	\
+	&& ((arc_seen_options & MASK) == 0))	\
+      target_flags |= MASK;			\
+    if (arc_selected_arch->dflags & CODE)	\
+      target_flags |= MASK;			\
+  } while (0);
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
+  do {						\
+    if ((arc_selected_cpu->flags & CODE)	\
+	&& (VAR == DEFAULT_##VAR))		\
+      VAR = VAL;				\
+    if (arc_selected_arch->dflags & CODE)	\
+      VAR = VAL;				\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Check options against architecture options.  Throw an error if
+     option is not allowed.  */
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
+  do {								\
+    if ((VAR == VAL)						\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      {								\
+	error ("%s is not available for %s architecture",	\
+	       DOC, arc_selected_arch->name);			\
+      }								\
+  } while (0);
+#define ARC_OPT(NAME, CODE, MASK, DOC)				\
+  do {								\
+    if ((target_flags & MASK)					\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      error ("%s is not available for %s architecture",		\
+	     DOC, arc_selected_arch->name);			\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Set Tune option.  */
+  if (arc_tune == TUNE_NONE)
+    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
 
   if (arc_size_opt_level == 3)
     optimize_size = 1;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index c02e1cd..f1705d5 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ARC_H
 #define GCC_ARC_H
 
+#include <stdbool.h>
+
 /* Things to do:
 
    - incscc, decscc?
@@ -39,6 +41,10 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
 #define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
 
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT	PROCESSOR_arc700
+#endif
+
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)	\
 	((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
@@ -74,9 +80,11 @@ along with GCC; see the file COPYING3.  If not see
       GNU_USER_TARGET_OS_CPP_BUILTINS (); \
     } \
   while (0)
-#endif
 
-/* Match the macros used in the assembler.  */
+#endif /* DEFAULT_LIBC == LIBC_UCLIBC */
+
+/* Macros enabled by specific command line option.  FIXME: to be
+   deprecatd.  */
 #define CPP_SPEC "\
 %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \
 %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \
@@ -85,34 +93,22 @@ along with GCC; see the file COPYING3.  If not see
 %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \
 %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \
 %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \
-%{mcpu=NPS400:-D__NPS400__} \
-%{mcpu=nps400:-D__NPS400__} \
-"
+%{mcpu=nps400:-D__NPS400__}"
 
 #define CC1_SPEC "\
 %{EB:%{EL:%emay not use both -EB and -EL}} \
 %{EB:-mbig-endian} %{EL:-mlittle-endian} \
 "
+extern const char *arc_cpu_to_as (int argc, const char **argv);
+
+#define EXTRA_SPEC_FUNCTIONS			\
+  { "cpu_to_as", arc_cpu_to_as },
+
+#define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "			\
+  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
 
-#define ASM_DEFAULT "-mARC700 -mEA"
-
-#define ASM_SPEC  "\
-%{mbig-endian|EB:-EB} %{EL} \
-%{mcpu=ARC600:-mARC600} \
-%{mcpu=ARC601:-mARC601} \
-%{mcpu=ARC700:-mARC700} \
-%{mcpu=ARC700:-mEA} \
-%{!mcpu=*:" ASM_DEFAULT "} \
-%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \
-%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \
-%{msimd} \
-%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \
-%{mcpu=ARC700|!mcpu=*:%{mlock}} \
-%{mcpu=ARC700|!mcpu=*:%{mswape}} \
-%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \
-%{mcpu=ARCHS:-mHS} \
-%{mcpu=ARCEM:-mEM} \
-%{matomic:-mlock}"
+#define OPTION_DEFAULT_SPECS						\
+  {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
 
 #if DEFAULT_LIBC == LIBC_UCLIBC
 /* Note that the default is to link against dynamic libraries, if they are
@@ -196,17 +192,11 @@ along with GCC; see the file COPYING3.  If not see
 #define TARGET_MMEDIUM_CALLS_DEFAULT 0
 #endif
 
-#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \
-  "%{mARC600|mA6: -mcpu=ARC600 %<mARC600 %<mA6}" \
-  "%{mARC601: -mcpu=ARC601 %<mARC601}" \
-  "%{mARC700|mA7: -mcpu=ARC700 %<mARC700 %<mA7}" \
-  "%{mbarrel_shifte*: -mbarrel-shifte%* %<mbarrel_shifte*}" \
-  "%{mEA: -mea %<mEA}" \
-  "%{mspfp_*: -mspfp-%* %<mspfp_*}" \
-  "%{mdpfp_*: -mdpfp-%* %<mdpfp_*}" \
-  "%{mdsp_pack*: -mdsp-pack%* %<mdsp_pack*}" \
-  "%{mmac_*: -mmac-%* %<mmac_*}" \
-  "%{multcost=*: -mmultcost=%* %<multcost=*}"
+#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS		   \
+  "%{mARC600|mA6: -mcpu=arc600 %<mARC600 %<mA6 %<mARC600}"	   \
+  "%{mARC601: -mcpu=arc601 %<mARC601}"				   \
+  "%{mARC700|mA7: -mcpu=arc700 %<mARC700 %<mA7}"		   \
+  "%{mEA: -mea %<mEA}"
 
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
@@ -252,20 +242,23 @@ along with GCC; see the file COPYING3.  If not see
    use conditional execution?  */
 #define TARGET_AT_DBR_CONDEXEC  (!TARGET_ARC700 && !TARGET_V2)
 
-#define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
-#define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
-#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700	\
-		       || arc_cpu == PROCESSOR_NPS400)
-#define TARGET_EM     (arc_cpu == PROCESSOR_ARCEM)
-#define TARGET_HS     (arc_cpu == PROCESSOR_ARCHS)
-#define TARGET_V2							\
-  ((arc_cpu == PROCESSOR_ARCHS) || (arc_cpu == PROCESSOR_ARCEM))
-
-/* Recast the cpu class to be the cpu attribute.  */
-#define arc_cpu_attr ((enum attr_cpu)arc_cpu)
-
-#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mARC700" }
+extern bool arc_arcem;
+extern bool arc_archs;
+extern bool arc_arc700;
+extern bool arc_arc600;
+extern bool arc_arc601;
+
+#define TARGET_ARC600 (arc_arc600)
+#define TARGET_ARC601 (arc_arc601)
+#define TARGET_ARC700 (arc_arc700)
+#define TARGET_EM (arc_arcem)
+#define TARGET_HS (arc_archs)
+#define TARGET_V2 (TARGET_EM || TARGET_HS)
+
+#ifdef ARC_MULTILIB_CPU_DEFAULT
+# ifndef MULTILIB_DEFAULTS
+#  define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT }
+# endif
 #endif
 
 #ifndef UNALIGNED_ACCESS_DEFAULT
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 715da31..6f757b6 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -231,11 +231,6 @@
 	 (eq_attr "is_CALL" "yes") (const_string "yes")]
 	(const_string "no")))
 
-
-;; Attribute describing the processor
-(define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
-  (const (symbol_ref "arc_cpu_attr")))
-
 ;; true for compact instructions (those with _s suffix)
 ;; "maybe" means compact unless we conditionalize the insn.
 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 4caf366..1578549 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -53,9 +53,12 @@ mARC700
 Target Report
 Same as -mA7.
 
+TargetVariable
+int arc_mpy_option = DEFAULT_arc_mpy_option
+
 mmpy-option=
-Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
--mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
+Target RejectNegative Joined
+-mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
 
 mdiv-rem
 Target Report Mask(DIVREM)
@@ -100,7 +103,7 @@ Target Report Mask(MUL64_SET)
 Generate mul64 and mulu64 instructions.
 
 mno-mpy
-Target Report Mask(NOMPY_SET)
+Target Report Mask(NOMPY_SET) Warn(%qs is deprecated)
 Do not generate mpy instructions for ARC700.
 
 mea
@@ -167,45 +170,6 @@ mcpu=
 Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
 -mcpu=CPU	Compile code for ARC variant CPU.
 
-Enum
-Name(processor_type) Type(enum processor_type)
-
-EnumValue
-Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(arc600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(arc601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(arcem) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(ARCHS) Value(PROCESSOR_ARCHS)
-
-EnumValue
-Enum(processor_type) String(archs) Value(PROCESSOR_ARCHS)
-
 msize-level=
 Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
 size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os.
@@ -308,25 +272,25 @@ Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
 ; Flags used by the assembler, but for which we define preprocessor
 ; macro symbols as well.
 mcrc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable variable polynomial CRC extension.
 
 mdsp-packa
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable DSP 3.1 Pack A extensions.
 
 mdvbf
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable dual viterbi butterfly extension.
 
 mmac-d16
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mmac-24
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mtelephony
-Target Report RejectNegative
+Target Report RejectNegative Warn(%qs is deprecated)
 Enable Dual and Single Operand Instructions for Telephony.
 
 mxy
@@ -343,7 +307,7 @@ Target Report
 Enable swap byte ordering extension instruction.
 
 mrtsc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable 64-bit Time-Stamp Counter extension instruction.
 
 EB
@@ -394,24 +358,6 @@ Target
 multcost=
 Target RejectNegative Joined
 
-; Unfortunately, listing the full option name gives us clashes
-; with OPT_opt_name being claimed for both opt_name and opt-name,
-; so we leave out the last character or more.
-mbarrel_shifte
-Target Joined
-
-mspfp_
-Target Joined
-
-mdpfp_
-Target Joined
-
-mdsp_pack
-Target Joined
-
-mmac_
-Target Joined
-
 matomic
 Target Report Mask(ATOMIC)
 Enable atomic instructions.
@@ -421,47 +367,47 @@ Target Report Mask(LL64)
 Enable double load/store instructions for ARC HS.
 
 mfpu=
-Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
+Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(DEFAULT_arc_fpu_build)
 Specify the name of the target floating point configuration.
 
 Enum
 Name(arc_fpu) Type(int)
 
 EnumValue
-Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
+Enum(arc_fpu) String(fpus) Value(FPU_FPUS)
 
 EnumValue
-Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+Enum(arc_fpu) String(fpud) Value(FPU_FPUD)
 
 EnumValue
-Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
+Enum(arc_fpu) String(fpuda) Value(FPU_FPUDA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_div) Value(FPU_FPUDA_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+Enum(arc_fpu) String(fpuda_fma) Value(FPU_FPUDA_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_all) Value(FPU_FPUDA_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
+Enum(arc_fpu) String(fpus_div) Value(FPU_FPUS_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
+Enum(arc_fpu) String(fpud_div) Value(FPU_FPUD_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
+Enum(arc_fpu) String(fpus_fma) Value(FPU_FPUS_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
+Enum(arc_fpu) String(fpud_fma) Value(FPU_FPUD_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+Enum(arc_fpu) String(fpus_all) Value(FPU_FPUS_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL)
 
 mtp-regno=
 Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25)
@@ -481,3 +427,6 @@ Enable use of NPS400 xld/xst extension.
 munaligned-access
 Target Report Var(unaligned_access) Init(UNALIGNED_ACCESS_DEFAULT)
 Enable unaligned word and halfword accesses to packed data.
+
+TargetVariable
+unsigned int arc_seen_options = 0
diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
new file mode 100644
index 0000000..c51b708
--- /dev/null
+++ b/gcc/config/arc/driver-arc.c
@@ -0,0 +1,80 @@
+/* Subroutines for the gcc driver.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu <claziss@synopsys.com>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+/* Returns command line parameters to pass to as.  */
+
+const char*
+arc_cpu_to_as (int argc, const char **argv)
+{
+  const char *name = NULL;
+  const arc_cpu_t *arc_selected_cpu;
+
+  /* No argument, check what is the default cpu.  */
+  if (argc == 0)
+    {
+      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
+    }
+  else
+    {
+      name = argv[0];
+      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
+	   arc_selected_cpu++)
+	{
+	  if (strcmp (arc_selected_cpu->name, name) == 0)
+	    break;
+	}
+    }
+
+  /* Checking the flags is only required with the old binutils
+     tools.  */
+  switch (arc_selected_cpu->arch)
+    {
+    case BASE_ARCH_em:
+      if (arc_selected_cpu->flags & FL_CD)
+	name = "-mcode-density";
+      else
+	name = "";
+      if (arc_selected_cpu->flags & FL_FPUDA)
+	name = concat ("-mfpuda ", name, NULL);
+      if (arc_selected_cpu->flags & FL_SPFP)
+	name = concat ("-mspfp ", name, NULL);
+      if (arc_selected_cpu->flags & FL_DPFP)
+	name = concat ("-mdpfp ", name, NULL);
+      return concat ("-mcpu=arcem ", name, NULL);
+    case BASE_ARCH_hs:
+      return "-mcpu=archs";
+    case BASE_ARCH_700:
+      return "-mcpu=arc700 -mEA";
+    case BASE_ARCH_6xx:
+      if (arc_selected_cpu->flags & FL_MUL64)
+	return "-mcpu=arc600 -mmul64 -mnorm";
+      if (arc_selected_cpu->flags & FL_MUL32x16)
+	return "-mcpu=arc600 -mdsp-packa -mnorm";
+      return "-mcpu=arc600 -mnorm";
+    default:
+      gcc_unreachable ();
+    }
+  return NULL;
+}
diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
new file mode 100644
index 0000000..5934f4f
--- /dev/null
+++ b/gcc/config/arc/genmultilib.awk
@@ -0,0 +1,203 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+# Transform CPU Information from arc-cpu.def to a
+# Representation that is understood by GCC's multilib Machinery.
+#
+# The Script works as a Filter from STDIN to STDOUT.
+#
+# FORMAT = "Makefile": Generate Makefile Snipet that sets some
+#                      MULTILIB_* Variables as needed.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+  n_reuse = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "# Auto-generated Makefile Snip"
+	  print "# Generated by    : ./gcc/config/arc/genmultilib.awk"
+	  print "# Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print "# Used by         : tmake_file from Makefile and genmultilib"
+	  print ""
+	}
+    }
+
+  comment = 2;
+
+  print
+}
+
+/^$/ {
+  # The first empty line stops copy-pasting the GPL comments
+  # from this file to the generated file.
+
+  comment = 0
+}
+
+
+/^ARC_CPU/ {
+  name = $2
+  #  gsub ("\"", "", name)
+
+  if ($4 != "0")
+    {
+      arch = $3
+      if (arch == "6xx")
+	arch = 601
+
+      n = split ($4, cpu_flg, "|")
+
+      line = "mcpu." arch
+      for (i = 1; i <= n; i++)
+	{
+	  if (cpu_flg[i] == "FL_MPYOPT_0")
+	    line = line "/mmpy-option.0"
+	  else if (cpu_flg[i] == "FL_MPYOPT_1")
+	    line = line "/mmpy-option.1"
+	  else if (cpu_flg[i] == "FL_MPYOPT_2")
+	    line = line "/mmpy-option.2"
+	  else if (cpu_flg[i] == "FL_MPYOPT_3")
+	    line = line "/mmpy-option.3"
+	  else if (cpu_flg[i] == "FL_MPYOPT_4")
+	    line = line "/mmpy-option.4"
+	  else if (cpu_flg[i] == "FL_MPYOPT_5")
+	    line = line "/mmpy-option.5"
+	  else if (cpu_flg[i] == "FL_MPYOPT_6")
+	    line = line "/mmpy-option.6"
+	  else if (cpu_flg[i] == "FL_MPYOPT_7")
+	    line = line "/mmpy-option.7"
+	  else if (cpu_flg[i] == "FL_MPYOPT_8")
+	    line = line "/mmpy-option.8"
+	  else if (cpu_flg[i] == "FL_MPYOPT_9")
+	    line = line "/mmpy-option.9"
+	  else if (cpu_flg[i] == "FL_CD")
+	    line = line "/mcode-density"
+	  else if (cpu_flg[i] == "FL_BS")
+	    line = line "/mbarrel-shifter"
+	  else if (cpu_flg[i] == "FL_DIVREM")
+	    line = line "/mdiv-rem"
+	  else if (cpu_flg[i] == "FL_NORM" \
+		   || cpu_flg[i] == "FL_SWAP")
+	    line = line "/mnorm"
+	  else if (cpu_flg[i] == "FL_FPU_FPUS")
+	    line = line "/mfpu.fpus"
+	  else if (cpu_flg[i] == "FL_FPU_FPUDA")
+	    line = line "/mfpu.fpuda"
+	  else if (cpu_flg[i] == "FL_FPU_FPUD_ALL")
+	    line = line "/mfpu.fpud_all"
+	  else if (cpu_flg[i] == "FL_LL64")
+	    line = line "/mll64"
+	  else if (cpu_flg[i] == "FL_MUL64")
+	    line = line "/mmul64"
+	  else if (cpu_flg[i] == "FL_MUL32x16")
+	    line = line "/mmul32x16"
+	  else if (cpu_flg[i] == "FL_FPX_QUARK")
+	    line = line "/quark"
+	  else if (cpu_flg[i] == "FL_SPFP")
+	    line = line "/spfp"
+	  else if (cpu_flg[i] == "FL_DPFP")
+	    line = line "/dpfp"
+	  else
+	    {
+	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
+	      exit 1
+	    }
+	}
+      line = "mcpu." name "=" line
+      reuse[n_reuse] = line
+      n_reuse++
+    }
+
+  core = name
+  cores[n_cores] = core
+  n_cores++
+}
+
+##################################################################
+#
+# We gathered all the Information, now build/output the following:
+#
+#    awk Variable         target Variable          FORMAT
+#  -----------------------------------------------------------
+#    m_options     <->    MULTILIB_OPTIONS         Makefile
+#    m_dirnames    <->    MULTILIB_DIRNAMES           "
+#
+##################################################################
+
+END {
+  m_options    = "\nMULTILIB_OPTIONS = "
+  m_dirnames   = "\nMULTILIB_DIRNAMES ="
+  m_reuse      = "\nMULTILIB_REUSE ="
+
+  sep = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options  = m_options sep "mcpu=" cores[c]
+      m_dirnames = m_dirnames " " cores[c]
+      sep = "/"
+    }
+
+  sep = ""
+  for (c = 0; c < n_reuse; c++)
+    {
+      m_reuse = m_reuse sep reuse[c]
+      sep = "\nMULTILIB_REUSE +="
+    }
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+      # Intended Target: ./gcc/config/arc/t-multilib
+
+      print m_options
+      print m_dirnames
+
+      ############################################################
+      # Legacy Aliases
+      ############################################################
+
+      print ""
+      print "# Aliases:"
+      print "MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mA6"
+      print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601"
+      print "MULTILIB_MATCHES += mcpu?arc700=mA7"
+      print "MULTILIB_MATCHES += mcpu?arc700=mARC700"
+    }
+}
diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk
new file mode 100644
index 0000000..24a93eb
--- /dev/null
+++ b/gcc/config/arc/genoptions.awk
@@ -0,0 +1,86 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "; Auto-generated Makefile Snip"
+	  print "; Generated by    : ./gcc/config/arc/genoptions.awk"
+	  print "; Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print ";"
+	}
+    }
+
+  comment = 2;
+
+  gsub ("^#", ";", $0)
+  print
+}
+
+/^$/ {
+    # The first empty line stops copy-pasting the GPL comments
+    # from this file to the generated file.
+    comment = 0
+}
+
+/^ARC_CPU/ {
+  name = $2
+  cores[n_cores] = name;
+  n_cores++
+}
+
+END {
+  m_option = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options = m_options "EnumValue\nEnum(processor_type) String(" \
+	cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n"
+    }
+
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+	print "\nEnum"
+	print "Name(processor_type) Type(enum processor_type)"
+	print "Known ARC CPUs (for use with the -mcpu= option):\n"
+	print m_options
+    }
+}
diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
index 4252e73..bdb1328 100644
--- a/gcc/config/arc/t-arc
+++ b/gcc/config/arc/t-arc
@@ -19,11 +19,30 @@
 
 TM_H += $(srcdir)/config/arc/arc-c.def
 
+driver-arc.o: $(srcdir)/config/arc/driver-arc.c \
+  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
 arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \
 $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arc/arc-c.c
 
+#Run `arc-cpus` if you changed something in arc-cpus.def
+
+.PHONY: arc-cpus
+
+arc-cpus: $(srcdir)/config/arc/t-multilib \
+	$(srcdir)/config/arc/arc-tables.opt
+
+$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk 	\
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
+$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
 # Local Variables:
 # mode: Makefile
 # End:
diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib
deleted file mode 100644
index c49a3fcc..0000000
--- a/gcc/config/arc/t-arc-newlib
+++ /dev/null
@@ -1,46 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm
-MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm
-#
-# Aliases:
-MULTILIB_MATCHES  = mcpu?ARC600=mcpu?arc600
-MULTILIB_MATCHES += mcpu?ARC600=mARC600
-MULTILIB_MATCHES += mcpu?ARC600=mA6
-MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
-MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
-MULTILIB_MATCHES += mcpu?ARC700=mA7
-MULTILIB_MATCHES += mcpu?ARC700=mARC700
-MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700
-MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem
-MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs
-MULTILIB_MATCHES += EL=mlittle-endian
-MULTILIB_MATCHES += EB=mbig-endian
-#
-# These don't make sense for the ARC700 default target:
-MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm*
-# And neither of the -mmul* options make sense without -mnorm:
-MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
-# Exclusions for ARC700
-MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16*
-# Exclusions for ARCv2EM
-MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16*
-# Exclusions for ARCv2HS
-MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm*
diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-arc-uClibc
deleted file mode 100644
index 11e81f1..0000000
--- a/gcc/config/arc/t-arc-uClibc
+++ /dev/null
@@ -1,20 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
new file mode 100644
index 0000000..5a36af6
--- /dev/null
+++ b/gcc/config/arc/t-multilib
@@ -0,0 +1,34 @@
+# Auto-generated Makefile Snip
+# Generated by    : ./gcc/config/arc/genmultilib.awk
+# Generated from  : ./gcc/config/arc/arc-cpu.def
+# Used by         : tmake_file from Makefile and genmultilib
+
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
+
+MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
+
+# Aliases:
+MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
+MULTILIB_MATCHES += mcpu?arc600=mARC600
+MULTILIB_MATCHES += mcpu?arc600=mA6
+MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601
+MULTILIB_MATCHES += mcpu?arc700=mA7
+MULTILIB_MATCHES += mcpu?arc700=mARC700
diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc
new file mode 100644
index 0000000..11e81f1
--- /dev/null
+++ b/gcc/config/arc/t-uClibc
@@ -0,0 +1,20 @@
+# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
+
+# Copyright (C) 2007-2016 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+
+# You should have received a copy of the GNU General Public License along
+# with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3f9c0a0..4399733 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13882,29 +13882,92 @@ values for @var{cpu} are
 @table @samp
 @opindex mA6
 @opindex mARC600
-@item ARC600
 @item arc600
 Compile for ARC600.  Aliases: @option{-mA6}, @option{-mARC600}.
 
-@item ARC601
 @item arc601
 @opindex mARC601
 Compile for ARC601.  Alias: @option{-mARC601}.
 
-@item ARC700
 @item arc700
 @opindex mA7
 @opindex mARC700
 Compile for ARC700.  Aliases: @option{-mA7}, @option{-mARC700}.
 This is the default when configured with @option{--with-cpu=arc700}@.
 
-@item ARCEM
 @item arcem
 Compile for ARC EM.
 
-@item ARCHS
 @item archs
 Compile for ARC HS.
+
+@item em
+@opindex em
+Compile for ARC EM cpu with no hardware extension.
+
+@item em4
+@opindex em4
+Compile for ARC EM4 cpu.
+
+@item em4_dmips
+@opindex em4_dmips
+Compile for ARC EM4 DMIPS cpu.
+
+@item em4_fpus
+@opindex em4_fpus
+Compile for ARC EM4 DMIPS cpu with single precision floating point
+extension.
+
+@item em4_fpuda
+@opindex em4_fpuda
+Compile for ARC EM4 DMIPS cpu with single precision floating point and
+double assists instructions.
+
+@item hs
+@opindex hs
+Compile for ARC HS cpu with no hardware extension, except the atomic
+instructions.
+
+@item hs34
+@opindex hs34
+Compile for ARC HS34 cpu.
+
+@item hs38
+@opindex hs38
+Compile for ARC HS38 cpu.
+
+@item hs38_linux
+@opindex hs38_linux
+Compile for ARC HS38 cpu with all hardware extensions on.
+
+@item arc600_norm
+@opindex arc600_norm
+Compile for ARC 600 cpu with norm instruction enabled.
+
+@item arc600_mul32x16
+@opindex arc600_mul32x16
+Compile for ARC 600 cpu with norm and mul32x16 instructions enabled.
+
+@item arc600_mul64
+@opindex arc600_mul64
+Compile for ARC 600 cpu with norm and mul64 instructions enabled.
+
+@item arc601_norm
+@opindex arc601_norm
+Compile for ARC 601 cpu with norm instruction enabled.
+
+@item arc601_mul32x16
+@opindex arc601_mul32x16
+Compile for ARC 601 cpu with norm and mul32x16 instructions enabled.
+
+@item arc601_mul64
+@opindex arc601_mul64
+Compile for ARC 601 cpu with norm and mul64 instructions enabled.
+
+@item nps400
+@opindex nps400
+Compile for ARC 700 on NPS400 chip.
+
 @end table
 
 @item -mdpfp
@@ -13931,7 +13994,8 @@ supported.  This is always enabled for @option{-mcpu=ARC700}.
 
 @item -mno-mpy
 @opindex mno-mpy
-Do not generate mpy instructions for ARC700.
+Do not generate mpy instructions for ARC700.  This instruction is
+deprecated.
 
 @item -mmul32x16
 @opindex mmul32x16
@@ -14138,12 +14202,14 @@ define preprocessor macro symbols.
 @item -mdsp-packa
 @opindex mdsp-packa
 Passed down to the assembler to enable the DSP Pack A extensions.
-Also sets the preprocessor symbol @code{__Xdsp_packa}.
+Also sets the preprocessor symbol @code{__Xdsp_packa}.  This option is
+deprecated.
 
 @item -mdvbf
 @opindex mdvbf
 Passed down to the assembler to enable the dual viterbi butterfly
-extension.  Also sets the preprocessor symbol @code{__Xdvbf}.
+extension.  Also sets the preprocessor symbol @code{__Xdvbf}.  This
+option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mlock
@@ -14155,19 +14221,19 @@ Conditional extension.  Also sets the preprocessor symbol
 @item -mmac-d16
 @opindex mmac-d16
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_d16}.
+@code{__Xxmac_d16}.  This option is deprecated.
 
 @item -mmac-24
 @opindex mmac-24
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_24}.
+@code{__Xxmac_24}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mrtsc
 @opindex mrtsc
 Passed down to the assembler to enable the 64-bit Time-Stamp Counter
 extension instruction.  Also sets the preprocessor symbol
-@code{__Xrtsc}.
+@code{__Xrtsc}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mswape
@@ -14180,7 +14246,7 @@ extension instruction.  Also sets the preprocessor symbol
 @opindex mtelephony
 Passed down to the assembler to enable dual and single operand
 instructions for telephony.  Also sets the preprocessor symbol
-@code{__Xtelephony}.
+@code{__Xtelephony}.  This option is deprecated.
 
 @item -mxy
 @opindex mxy
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-10-10 13:28   ` [PATCH] " Claudiu Zissulescu
@ 2016-10-12 20:02     ` Andrew Burgess
  2016-10-13  8:42       ` Claudiu Zissulescu
  2016-10-31 15:48       ` Claudiu Zissulescu
  0 siblings, 2 replies; 18+ messages in thread
From: Andrew Burgess @ 2016-10-12 20:02 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-10-10 15:26:47 +0200]:

> Hi Andrew,
> 
> This is updated patch of the original sent to mailing list some while ago.
> 
> What is new:
>      - Do not use MULTILIB_REUSE as its semantic changed, and the old one was causing issues while building.
>      - Update invoke.texi documentation adding nps400 option to mcpu.
> 
> This patch is important as it changes the way how we handle CPU
> variations and multilib support. It will be great if you can include
> this patch on your review list before any other one.

Sorry it's taken soooo long to review this patch.

In general I like this, and think it's a step in the right direction.
I have a few pretty minor concerns, but hopefully nothing too
contentious.

In general I like the use of the *.def files, but my only concern is
the lack of explanation in any of them about what they're for.  It
would be nice if each had a summary of what each field represents to
make it easier to add new entries.

The use of arc_seen_options can, I think be replaced by using
global_opts_seen.x_target_flags, or maybe there's a detail I'm not
understanding, in which case maybe a comment somewhere to explain why
those two things are different.

The only thing I dislike in this patch is the switch from 'arc_cpu' to
a set of global boolean flags.  I can't see why we'd ever want more
than one of those architecture flags to be true, so I'd rather we
switched back to an enum if that's possible.

[ I've left my review comments in line below too, but the above is a
summary of everything, there's nothing additional below. ]

Thanks,
Andrew

> 
> Thanks,
> Claudiu
> 
> gcc/
> 2016-05-09  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc-arch.h: New file.
> 	* config/arc/arc-arches.def: Likewise.
> 	* config/arc/arc-cpus.def: Likewise.
> 	* config/arc/arc-options.def: Likewise.
> 	* config/arc/t-multilib: Likewise.
> 	* config/arc/genmultilib.awk: Likewise.
> 	* config/arc/genoptions.awk: Likewise.
> 	* config/arc/arc-tables.opt: Likewise.
> 	* config/arc/driver-arc.c: Likewise.
> 	* common/config/arc/arc-common.c (arc_handle_option): Trace
> 	toggled options.
> 	* config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra
> 	options; check for supported cpu against arc-cpus.def file.
> 	(arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define
> 	TARGET_CPU_BUILD macro; add driver-arc.o as an extra object.
> 	* config/arc/arc-c.def: Add emacs local variables.
> 	* config/arc/arc-opts.h (processor_type): Use arc-cpus.def file.
> 	(FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA)
> 	(FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL)
> 	(FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines.
> 	(DEFAULT_arc_fpu_build): Define.
> 	(DEFAULT_arc_mpy_option): Define.
> 	* config/arc/arc-protos.h (arc_init): Delete.
> 	* config/arc/arc.c (arc_cpu_name): New variable.
> 	(arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs)
> 	(arc_arc700, arc_arc600, arc_arc601): New variable.
> 	(arc_init): Add static; remove selection of default tune value,
> 	cleanup obsolete error messages.
> 	(arc_override_options): Make use of .def files for selecting the
> 	right cpu and option configurations.
> 	* config/arc/arc.h (stdbool.h): Include.
> 	(TARGET_CPU_DEFAULT): Define.
> 	(CPP_SPEC): Remove mcpu=NPS400 handling.
> 	(arc_cpu_to_as): Declare.
> 	(EXTRA_SPEC_FUNCTIONS): Define.
> 	(OPTION_DEFAULT_SPECS): Likewise.
> 	(ASM_DEFAULT): Remove.
> 	(ASM_SPEC): Use arc_cpu_to_as.
> 	(DRIVER_SELF_SPECS): Remove deprecated options.
> 	(arc_arc700, arc_arc600, arc_arc601, arc_arcem, arc_archs):
> 	Declare.
> 	(TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM)
> 	(TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_arc*
> 	variables.
> 	(MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT.
> 	* config/arc/arc.md (attr_cpu): Remove.
> 	* config/arc/arc.opt (arc_mpy_option): Make it target variable.
> 	(mno-mpy): Deprecate.
> 	(mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM)
> 	(mcpu=ARCHS): Remove.
> 	(mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc):
> 	Deprecate.
> 	(mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove.
> 	(arc_fpu): Use new defines.
> 	(arc_seen_options): New target variable.
> 	* config/arc/t-arc (driver-arc.o): New target.
> 	(arc-cpus, t-multilib, arc-tables.opt): Likewise.
> 	* config/arc/t-arc-newlib: Delete.
> 	* config/arc/t-arc-uClibc: Renamed to t-uClibc.
> 	* doc/invoke.texi (ARC): Update arc options.
> ---
>  gcc/common/config/arc/arc-common.c | 162 ++++++++++++++++++++---------
>  gcc/config.gcc                     |  47 +++++----
>  gcc/config/arc/arc-arch.h          | 120 ++++++++++++++++++++++
>  gcc/config/arc/arc-arches.def      |  35 +++++++
>  gcc/config/arc/arc-c.def           |   4 +
>  gcc/config/arc/arc-cpus.def        |  47 +++++++++
>  gcc/config/arc/arc-options.def     |  69 +++++++++++++
>  gcc/config/arc/arc-opts.h          |  47 +++++++--
>  gcc/config/arc/arc-protos.h        |   1 -
>  gcc/config/arc/arc-tables.opt      |  90 ++++++++++++++++
>  gcc/config/arc/arc.c               | 186 ++++++++++++++++++---------------
>  gcc/config/arc/arc.h               |  91 ++++++++---------
>  gcc/config/arc/arc.md              |   5 -
>  gcc/config/arc/arc.opt             | 109 ++++++--------------
>  gcc/config/arc/driver-arc.c        |  80 +++++++++++++++
>  gcc/config/arc/genmultilib.awk     | 203 +++++++++++++++++++++++++++++++++++++
>  gcc/config/arc/genoptions.awk      |  86 ++++++++++++++++
>  gcc/config/arc/t-arc               |  19 ++++
>  gcc/config/arc/t-arc-newlib        |  46 ---------
>  gcc/config/arc/t-arc-uClibc        |  20 ----
>  gcc/config/arc/t-multilib          |  34 +++++++
>  gcc/config/arc/t-uClibc            |  20 ++++
>  gcc/doc/invoke.texi                |  90 +++++++++++++---
>  23 files changed, 1235 insertions(+), 376 deletions(-)
>  create mode 100644 gcc/config/arc/arc-arch.h
>  create mode 100644 gcc/config/arc/arc-arches.def
>  create mode 100644 gcc/config/arc/arc-cpus.def
>  create mode 100644 gcc/config/arc/arc-options.def
>  create mode 100644 gcc/config/arc/arc-tables.opt
>  create mode 100644 gcc/config/arc/driver-arc.c
>  create mode 100644 gcc/config/arc/genmultilib.awk
>  create mode 100644 gcc/config/arc/genoptions.awk
>  delete mode 100644 gcc/config/arc/t-arc-newlib
>  delete mode 100644 gcc/config/arc/t-arc-uClibc
>  create mode 100644 gcc/config/arc/t-multilib
>  create mode 100644 gcc/config/arc/t-uClibc
> 
> diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
> index 5b687fb..2898860 100644
> --- a/gcc/common/config/arc/arc-common.c
> +++ b/gcc/common/config/arc/arc-common.c
> @@ -2,6 +2,7 @@
>     Copyright (C) 1994-2016 Free Software Foundation, Inc.
>     Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
>  		on behalf of Synopsys Inc.
> +		Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
>  
>  This file is part of GCC.
>  
> @@ -61,17 +62,19 @@ static const struct default_options arc_option_optimization_table[] =
>  
>  /*  Process options.  */
>  static bool
> -arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
> +arc_handle_option (struct gcc_options *opts,
> +		   struct gcc_options *opts_set ATTRIBUTE_UNUSED,
>  		   const struct cl_decoded_option *decoded,
>  		   location_t loc)
>  {
>    size_t code = decoded->opt_index;
>    int value = decoded->value;
>    const char *arg = decoded->arg;
> +  static int mcpu_seen = PROCESSOR_NONE;
> +  char *p;
>  
>    switch (code)
>      {
> -      static int mcpu_seen = PROCESSOR_NONE;
>      case OPT_mcpu_:
>        /* N.B., at this point arc_cpu has already been set to its new value by
>  	 our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless.  */
> @@ -79,71 +82,130 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
>        if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
>  	warning_at (loc, 0, "multiple -mcpu= options specified.");
>        mcpu_seen = value;
> +      break;
> +
> +    case OPT_mmpy_option_:
> +      p = ASTRDUP (arg);
>  
> -      switch (value)
> +      if (!strcmp (p, "0")
> +	  || !strcmp (p, "none"))
> +	opts->x_arc_mpy_option = 0;
> +      else if (!strcmp (p, "1")
> +	  || !strcmp (p, "w"))
>  	{
> -	case PROCESSOR_NPS400:
> -	  if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) )
> -	    opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1;
> -	  /* Fall through */
> -	case PROCESSOR_ARC600:
> -	case PROCESSOR_ARC700:
> -	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
> -	    opts->x_target_flags |= MASK_BARREL_SHIFTER;
> -	  break;
> -	case PROCESSOR_ARC601:
> -	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
> -	    opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
> -	  break;
> -	case PROCESSOR_ARCHS:
> -	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
> -	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
> -	    opts->x_target_flags |= MASK_CODE_DENSITY;	  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
> -	    opts->x_target_flags |= MASK_NORM_SET;	  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
> -	    opts->x_target_flags |= MASK_SWAP_SET;	  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
> -	    opts->x_target_flags |= MASK_DIVREM;	  /* Default: on.  */
> -	  break;
> -
> -	case PROCESSOR_ARCEM:
> -	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
> -	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
> -	    opts->x_target_flags &= ~MASK_CODE_DENSITY;	  /* Default: off.  */
> -	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
> -	    opts->x_target_flags &= ~MASK_NORM_SET;	  /* Default: off.  */
> -	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
> -	    opts->x_target_flags &= ~MASK_SWAP_SET;	  /* Default: off.  */
> -	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
> -	    opts->x_target_flags &= ~MASK_DIVREM;	  /* Default: off.  */
> -	  break;
> -	default:
> -	  gcc_unreachable ();
> +	  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);
> +
>        break;
>  
> -    case OPT_mmpy_option_:
> -      if (value < 0 || value > 9)
> -	error_at (loc, "bad value %qs for -mmpy-option switch", arg);
> +    case OPT_mcode_density:
> +      opts->x_arc_seen_options |= MASK_CODE_DENSITY;
> +      break;
> +
> +    case OPT_mdiv_rem:
> +      opts->x_arc_seen_options |= MASK_DIVREM;
> +      break;
> +
> +    case OPT_mnorm:
> +      opts->x_arc_seen_options |= MASK_NORM_SET;
> +      break;
> +
> +    case OPT_matomic:
> +      opts->x_arc_seen_options |= MASK_ATOMIC;
> +      break;
> +
> +    case OPT_mll64:
> +      opts->x_arc_seen_options |= MASK_LL64;
> +      break;
> +
> +    case OPT_mbarrel_shifter:
> +      opts->x_arc_seen_options |= MASK_BARREL_SHIFTER;
> +      break;
> +
> +    case OPT_mswap:
> +      opts->x_arc_seen_options |= MASK_SWAP_SET;
> +      break;
> +
> +    case OPT_mmul64:
> +      opts->x_arc_seen_options |= MASK_MUL64_SET;
> +      break;
> +
> +    case OPT_mmul32x16:
> +      opts->x_arc_seen_options |= MASK_MULMAC_32BY16_SET;
> +      break;
> +
> +    case OPT_mEA:
> +      opts->x_arc_seen_options |= MASK_EA_SET;
> +      break;
> +
> +    case OPT_mspfp:
> +    case OPT_mspfp_compact:
> +    case OPT_mspfp_fast:
> +      opts->x_arc_seen_options |= MASK_SPFP_COMPACT_SET;
> +      break;
> +
> +    case OPT_mdpfp:
> +    case OPT_mdpfp_compact:
> +    case OPT_mdpfp_fast:
> +      opts->x_arc_seen_options |= MASK_DPFP_COMPACT_SET;
> +      break;
> +
> +    case OPT_margonaut:
> +      opts->x_arc_seen_options |= MASK_ARGONAUT_SET;
> +      break;
> +
> +    case OPT_msimd:
> +      opts->x_arc_seen_options |= MASK_SIMD_SET;
> +      break;

I'd be interested to know if you considered making use of
opts_seen->x_target_flags instead of the new x_arc_seen_options?  And
if you did, but rejected it, why it doesn't solve the problem.  I
think making the switch would mean a lot of the new code above can
go.

> +
> +    default:
>        break;
>      }
>  
>    return true;
>  }
>  
> +#undef  TARGET_OPTION_INIT_STRUCT
>  #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
> +
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
>  #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
> -#define TARGET_HANDLE_OPTION arc_handle_option
>  
>  #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
>  
> -/* We default to ARC700, which has the barrel shifter enabled.  */
> -#define TARGET_DEFAULT_TARGET_FLAGS \
> -  (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
> +#undef  TARGET_DEFAULT_TARGET_FLAGS
> +#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET)
>  
> +#undef  TARGET_HANDLE_OPTION
> +#define TARGET_HANDLE_OPTION arc_handle_option
>  
>  #include "common/common-target-def.h"
>  
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 8fd07c5..50dca89 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -318,6 +318,7 @@ arc*-*-*)
>  	cpu_type=arc
>  	c_target_objs="arc-c.o"
>  	cxx_target_objs="arc-c.o"
> +	extra_options="${extra_options} arc/arc-tables.opt"
>  	;;
>  arm*-*-*)
>  	cpu_type=arm
> @@ -991,13 +992,12 @@ alpha*-dec-*vms*)
>  	;;
>  arc*-*-elf*)
>  	extra_headers="arc-simd.h"
> -	tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
> -	tmake_file="arc/t-arc-newlib arc/t-arc"
> -	case x"${with_cpu}" in
> -	  xarc600|xarc601|xarc700)
> -		target_cpu_default="TARGET_CPU_$with_cpu"
> -		;;
> -	esac
> +	tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
> +	tmake_file="arc/t-multilib arc/t-arc"
> +	extra_gcc_objs="driver-arc.o"
> +	if test "x$with_cpu" != x; then
> +		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
> +	fi
>  	if test x${with_endian} = x; then
>  		case ${target} in
>  		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
> @@ -1014,15 +1014,14 @@ arc*-*-elf*)
>  	;;
>  arc*-*-linux-uclibc*)
>  	extra_headers="arc-simd.h"
> -	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
> -	tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc"
> +	tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
> +	tmake_file="${tmake_file} arc/t-uClibc arc/t-arc"
>  	tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0"
>  	tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1"
> -	case x"${with_cpu}" in
> -	  xarc600|xarc601|xarc700)
> -		target_cpu_default="TARGET_CPU_$with_cpu"
> -		;;
> -	esac
> +	extra_gcc_objs="driver-arc.o"
> +	if test "x$with_cpu" != x; then
> +		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
> +	fi
>  	if test x${with_endian} = x; then
>  		case ${target} in
>  		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
> @@ -3605,15 +3604,19 @@ case "${target}" in
>  		done
>  		;;
>  
> -	arc*-*-*) # was:	arc*-*-linux-uclibc)
> +	arc*-*-*)
>  		supported_defaults="cpu"
> -		case $with_cpu in
> -		  arc600|arc601|arc700)
> -			;;
> -		  *) echo "Unknown cpu type"
> -			exit 1
> -			;;
> -		esac
> +
> +		if [ x"$with_cpu" = x ] \
> +		    || grep "^ARC_CPU ($with_cpu," \
> +		       ${srcdir}/config/arc/arc-cpus.def \
> +		       > /dev/null; then
> +		 # Ok
> +		 true
> +		else
> +		 echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
> +		 exit 1
> +		fi
>  		;;
>  
>  	arm*-*-*)
> diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
> new file mode 100644
> index 0000000..7994543
> --- /dev/null
> +++ b/gcc/config/arc/arc-arch.h
> @@ -0,0 +1,120 @@
> +/* Definitions of types that are used to store ARC architecture and
> +   device information.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +   Contributed by Claudiu Zissulescu (claziss@synopsys.com)
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#ifndef GCC_ARC_ARCH_H
> +#define GCC_ARC_ARCH_H
> +
> +#ifndef IN_LIBGCC2
> +/* Architecture selection types.  */
> +
> +enum cpu_flags
> +  {
> +#define ARC_OPT(NAME, CODE, MASK, DOC)	    NAME = CODE,
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE,
> +#include "arc-options.def"
> +#undef ARC_OPT
> +#undef ARC_OPTX
> +    FL_END
> +  };
> +
> +
> +/* ARC architecture variants.  */
> +
> +enum base_architecture
> +  {
> +    BASE_ARCH_NONE,
> +#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)  BASE_ARCH_##ARCH,
> +#include "arc-arches.def"
> +#undef ARC_ARCH
> +    BASE_ARCH_END
> +  };
> +
> +
> +/* Tune variants.  Needs to match the attr_tune enum.  */
> +
> +enum arc_tune_attr
> +  {
> +    ARC_TUNE_NONE,
> +    ARC_TUNE_ARC600,
> +    ARC_TUNE_ARC700_4_2_STD,
> +    ARC_TUNE_ARC700_4_2_XMAC
> +  };
> +
> +/* CPU specific properties.  */
> +
> +typedef struct
> +{
> +  /* CPU name.  */
> +  const char *const name;
> +
> +  /* Architecture class.  */
> +  enum base_architecture arch;
> +
> +  /* Specific flags.  */
> +  const unsigned long long flags;
> +
> +  /* Tune value.  */
> +  enum arc_tune_attr tune;
> +} arc_cpu_t;
> +
> +
> +/* Architecture specific propoerties.  */
> +
> +typedef struct
> +{
> +  /* Architecture name.  */
> +  const char *const name;
> +
> +  /* Architecture class.  */
> +  enum base_architecture arch;
> +
> +  /* All allowed flags for this architecture.  */
> +  const unsigned long long flags;
> +
> +  /* Default flags for this architecture.  It is a subset of
> +     FLAGS.  */
> +  const unsigned long long dflags;
> +} arc_arch_t;
> +
> +
> +
> +const arc_arch_t arc_arch_types[] =
> +  {
> +    {"none", BASE_ARCH_NONE, 0, 0},
> +#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)	\
> +    {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS},
> +#include "arc-arches.def"
> +#undef ARC_ARCH
> +    {NULL, BASE_ARCH_END, 0, 0}
> +  };
> +
> +const arc_cpu_t arc_cpu_types[] =
> +  {
> +    {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE},
> +#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
> +    {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE},
> +#include "arc-cpus.def"
> +#undef ARC_CPU
> +    {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE}
> +  };
> +
> +#endif
> +#endif /* GCC_ARC_ARCH_H */
> diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
> new file mode 100644
> index 0000000..bd76124
> --- /dev/null
> +++ b/gcc/config/arc/arc-arches.def
> @@ -0,0 +1,35 @@
> +/* ARC ARCH architectures.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
> +	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
> +	  | FL_SIMD | FL_FPUDA, 0)
> +ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
> +	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
> +	  | FL_FPUS | FL_FPUD,						\
> +	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
> +ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
> +	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
> +ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
> +	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
> +	  FL_BS | FL_NORM | FL_SWAP)
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
> index 065e973..4cfd7b6 100644
> --- a/gcc/config/arc/arc-c.def
> +++ b/gcc/config/arc/arc-c.def
> @@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__",     TARGET_EM)
>  ARC_C_DEF ("__HS__",     TARGET_HS)
>  ARC_C_DEF ("__Xnorm",    TARGET_NORM)
>  ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER)
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
> new file mode 100644
> index 0000000..381507c
> --- /dev/null
> +++ b/gcc/config/arc/arc-cpus.def
> @@ -0,0 +1,47 @@
> +/* ARC CPU architectures.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +ARC_CPU (em,	    em, 0, NONE)
> +ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
> +ARC_CPU (em4,	    em, FL_CD, NONE)
> +ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
> +ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
> +ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
> +
> +ARC_CPU (hs,	     hs, 0, NONE)
> +ARC_CPU (archs,	     hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
> +ARC_CPU (hs34,	     hs, FL_MPYOPT_2, NONE)
> +ARC_CPU (hs38,	     hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE)
> +ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE)
> +
> +ARC_CPU (arc600,	  6xx, FL_BS, ARC600)
> +ARC_CPU (arc600_norm,	  6xx, FL_BS|FL_NORM, ARC600)
> +ARC_CPU (arc600_mul64,	  6xx, FL_BS|FL_NORM|FL_MUL64, ARC600)
> +ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600)
> +ARC_CPU (arc601,	  6xx, 0, ARC600)
> +ARC_CPU (arc601_norm,	  6xx, FL_NORM, ARC600)
> +ARC_CPU (arc601_mul64,	  6xx, FL_NORM|FL_MUL64, ARC600)
> +ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600)
> +
> +ARC_CPU (arc700, 700, 0, ARC700_4_2_STD)
> +ARC_CPU (nps400, 700, 0, ARC700_4_2_STD)
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
> new file mode 100644
> index 0000000..083719a
> --- /dev/null
> +++ b/gcc/config/arc/arc-options.def
> @@ -0,0 +1,69 @@
> +/* ARC options.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
> +ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
> +ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
> +
> +ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
> +ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
> +ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
> +ARC_OPT (FL_SWAP,     (1ULL << 7), MASK_SWAP_SET,	   "swap")
> +ARC_OPT (FL_MUL64,    (1ULL << 8), MASK_MUL64_SET,	   "mul64")
> +ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16")
> +
> +ARC_OPT (FL_EA,	      (1ULL << 11), MASK_EA_SET,	   "extended arithmetics")
> +ARC_OPT (FL_SPFP,     (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX")
> +ARC_OPT (FL_DPFP,     (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX")
> +ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET,	   "argonaut")
> +ARC_OPT (FL_SIMD,     (1ULL << 15), MASK_SIMD_SET,	   "simd")
> +
> +ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w")
> +ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1")
> +ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2")
> +ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3")
> +ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4")
> +ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5")
> +ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy")
> +ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd")
> +ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw")
> +
> +ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option")
> +ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option")
> +
> +ARC_OPTX (FL_FPU_FPUS,	    (1ULL << 26), arc_fpu_build, FPU_FPUS,	"mfpu=fpus")
> +ARC_OPTX (FL_FPU_FPUS_DIV,  (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV,	"mfpu=fpus_div")
> +ARC_OPTX (FL_FPU_FPUS_FMA,  (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA,	"mfpu=fpus_fma")
> +ARC_OPTX (FL_FPU_FPUS_ALL,  (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL,	"mfpu=fpus_all")
> +ARC_OPTX (FL_FPU_FPUDA,	    (1ULL << 30), arc_fpu_build, FPU_FPUDA,	"mfpu=fpuda")
> +ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div")
> +ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma")
> +ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all")
> +ARC_OPTX (FL_FPU_FPUD,	    (1ULL << 34), arc_fpu_build, FPU_FPUD,	"mfpu=fpud")
> +ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV,	"mfpu=fpud_div")
> +ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA,	"mfpu=fpud_fma")
> +ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL,	"mfpu=fpud_all")
> +
> +ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
> +ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
> +ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
> index cbd7898..81446b4 100644
> --- a/gcc/config/arc/arc-opts.h
> +++ b/gcc/config/arc/arc-opts.h
> @@ -18,15 +18,16 @@
>     along with GCC; see the file COPYING3.  If not see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef ARC_OPTS_H
> +#define ARC_OPTS_H
> +
>  enum processor_type
>  {
> -  PROCESSOR_NONE,
> -  PROCESSOR_ARC600,
> -  PROCESSOR_ARC601,
> -  PROCESSOR_ARC700,
> -  PROCESSOR_NPS400,
> -  PROCESSOR_ARCEM,
> -  PROCESSOR_ARCHS
> +  PROCESSOR_NONE = 0,
> +#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)  PROCESSOR_##NAME,
> +#include "arc-cpus.def"
> +#undef ARC_CPU
> +  PROCESSOR_generic
>  };
>  
>  /* Single precision floating point.  */
> @@ -48,3 +49,35 @@ enum processor_type
>  /* Double precision floating point assist operations.  */
>  #define FPX_DP    0x0100
>  
> +/* fpus option combi.  */
> +#define FPU_FPUS  (FPU_SP | FPU_SC)
> +/* fpud option combi.  */
> +#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
> +/* fpuda option combi.  */
> +#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
> +/* fpuda_div option combi.  */
> +#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
> +/* fpuda_fma option combi.  */
> +#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
> +/* fpuda_all option combi.  */
> +#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
> +/* fpus_div option combi.  */
> +#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
> +/* fpus_fma option combi.  */
> +#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
> +/* fpus_all option combi.  */
> +#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
> +/* fpud_div option combi.  */
> +#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
> +/* fpud_fma option combi.  */
> +#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
> +/* fpud_all option combi.  */
> +#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
> +
> +/* Default FPU option value.  */
> +#define DEFAULT_arc_fpu_build 0x10000000
> +
> +/* Default MPY option value.  */
> +#define DEFAULT_arc_mpy_option -1
> +
> +#endif /* ARC_OPTS_H */
> diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
> index ad5d4d3..d1266b4 100644
> --- a/gcc/config/arc/arc-protos.h
> +++ b/gcc/config/arc/arc-protos.h
> @@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
>  #endif /* TREE_CODE */
>  
>  
> -extern void arc_init (void);
>  extern unsigned int arc_compute_frame_size (int);
>  extern bool arc_ccfsm_branch_deleted_p (void);
>  extern void arc_ccfsm_record_branch_deleted (void);
> diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
> new file mode 100644
> index 0000000..0e7c50c
> --- /dev/null
> +++ b/gcc/config/arc/arc-tables.opt
> @@ -0,0 +1,90 @@
> +; Auto-generated Makefile Snip
> +; Generated by    : ./gcc/config/arc/genoptions.awk
> +; Generated from  : ./gcc/config/arc/arc-cpu.def
> +;
> +; Copyright (C) 2016 Free Software Foundation, Inc.
> +;
> +; This file is part of GCC.
> +;
> +; GCC is free software; you can redistribute it and/or modify it under
> +; the terms of the GNU General Public License as published by the Free
> +; Software Foundation; either version 3, or (at your option) any later
> +; version.
> +;
> +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +; for more details.
> +;
> +; You should have received a copy of the GNU General Public License
> +; along with GCC; see the file COPYING3.  If not see
> +; <http://www.gnu.org/licenses/>.
> +
> +Enum
> +Name(processor_type) Type(enum processor_type)
> +Known ARC CPUs (for use with the -mcpu= option):
> +
> +EnumValue
> +Enum(processor_type) String(em) Value(PROCESSOR_em)
> +
> +EnumValue
> +Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
> +
> +EnumValue
> +Enum(processor_type) String(em4) Value(PROCESSOR_em4)
> +
> +EnumValue
> +Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips)
> +
> +EnumValue
> +Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
> +
> +EnumValue
> +Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
> +
> +EnumValue
> +Enum(processor_type) String(hs) Value(PROCESSOR_hs)
> +
> +EnumValue
> +Enum(processor_type) String(archs) Value(PROCESSOR_archs)
> +
> +EnumValue
> +Enum(processor_type) String(hs34) Value(PROCESSOR_hs34)
> +
> +EnumValue
> +Enum(processor_type) String(hs38) Value(PROCESSOR_hs38)
> +
> +EnumValue
> +Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux)
> +
> +EnumValue
> +Enum(processor_type) String(arc600) Value(PROCESSOR_arc600)
> +
> +EnumValue
> +Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm)
> +
> +EnumValue
> +Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64)
> +
> +EnumValue
> +Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16)
> +
> +EnumValue
> +Enum(processor_type) String(arc601) Value(PROCESSOR_arc601)
> +
> +EnumValue
> +Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm)
> +
> +EnumValue
> +Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64)
> +
> +EnumValue
> +Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16)
> +
> +EnumValue
> +Enum(processor_type) String(arc700) Value(PROCESSOR_arc700)
> +
> +EnumValue
> +Enum(processor_type) String(nps400) Value(PROCESSOR_nps400)
> +
> +
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 5e8d6b4..cfb3531 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -64,7 +64,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "alias.h"
>  
>  /* Which cpu we're compiling for (ARC600, ARC601, ARC700).  */
> -static const char *arc_cpu_string = "";
> +static char arc_cpu_name[10] = "";
> +static const char *arc_cpu_string = arc_cpu_name;
>  
>  /* ??? Loads can handle any constant, stores can only handle small ones.  */
>  /* OTOH, LIMMs cost extra, so their usefulness is limited.  */
> @@ -241,6 +242,16 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
>  						enum by_pieces_operation op,
>  						bool);
>  
> +static const arc_cpu_t *arc_selected_cpu;
> +static const arc_arch_t *arc_selected_arch;
> +
> +/* Global var which sets the current compilation architecture.  */
> +bool arc_arcem = false;
> +bool arc_archs = false;
> +bool arc_arc700 = false;
> +bool arc_arc600 = false;
> +bool arc_arc601 = false;
> +
>  /* Implements target hook vector_mode_supported_p.  */
>  
>  static bool
> @@ -668,47 +679,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
>  
>  /* Called by OVERRIDE_OPTIONS to initialize various things.  */
>  
> -void
> +static void
>  arc_init (void)
>  {
> -  enum attr_tune tune_dflt = TUNE_NONE;
> -
> -  switch (arc_cpu)
> -    {
> -    case PROCESSOR_ARC600:
> -      arc_cpu_string = "ARC600";
> -      tune_dflt = TUNE_ARC600;
> -      break;
> -
> -    case PROCESSOR_ARC601:
> -      arc_cpu_string = "ARC601";
> -      tune_dflt = TUNE_ARC600;
> -      break;
> -
> -    case PROCESSOR_ARC700:
> -      arc_cpu_string = "ARC700";
> -      tune_dflt = TUNE_ARC700_4_2_STD;
> -      break;
> -
> -    case PROCESSOR_NPS400:
> -      arc_cpu_string = "NPS400";
> -      tune_dflt = TUNE_ARC700_4_2_STD;
> -      break;
> -
> -    case PROCESSOR_ARCEM:
> -      arc_cpu_string = "EM";
> -      break;
> -
> -    case PROCESSOR_ARCHS:
> -      arc_cpu_string = "HS";
> -      break;
> -
> -    default:
> -      gcc_unreachable ();
> -    }
> -
> -  if (arc_tune == TUNE_NONE)
> -    arc_tune = tune_dflt;
>    /* Note: arc_multcost is only used in rtx_cost if speed is true.  */
>    if (arc_multcost < 0)
>      switch (arc_tune)
> @@ -739,18 +712,10 @@ arc_init (void)
>  	break;
>        }
>  
> -  /* Support mul64 generation only for ARC600.  */
> -  if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY))
> -      error ("-mmul64 not supported for ARC700 or ARCv2");
> -
>    /* MPY instructions valid only for ARC700 or ARCv2.  */
>    if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
>        error ("-mno-mpy supported only for ARC700 or ARCv2");
>  
> -  /* mul/mac instructions only for ARC600.  */
> -  if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY))
> -      error ("-mmul32x16 supported only for ARC600 or ARC601");
> -
>    if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
>        error ("-mno-dpfp-lrsr supported only with -mdpfp");
>  
> @@ -763,23 +728,11 @@ arc_init (void)
>    if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
>      error ("-mspfp_fast not available on ARC600 or ARC601");
>  
> -  /* FPX-3. No FPX extensions on pre-ARC600 cores.  */
> -  if ((TARGET_DPFP || TARGET_SPFP)
> -      && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
> -    error ("FPX extensions not available on pre-ARC600 cores");
> -
> -  /* FPX-4.  No FPX extensions mixed with FPU extensions for ARC HS
> -     cpus.  */
> -  if ((TARGET_DPFP || TARGET_SPFP)
> -      && TARGET_HARD_FLOAT
> -      && TARGET_HS)
> +  /* FPX-4.  No FPX extensions mixed with FPU extensions.  */
> +  if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
> +      && TARGET_HARD_FLOAT)
>      error ("No FPX/FPU mixing allowed");
>  
> -  /* Only selected multiplier configurations are available for HS.  */
> -  if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
> -		    || (arc_mpy_option == 1)))
> -    error ("This multiplier configuration is not available for HS cores");
> -
>    /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic.  */
>    if (flag_pic && TARGET_ARC600_FAMILY)
>      {
> @@ -789,26 +742,6 @@ arc_init (void)
>        flag_pic = 0;
>      }
>  
> -  if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS))
> -    error ("-matomic is only supported for ARC700 or ARC HS cores");
> -
> -  /* ll64 ops only available for HS.  */
> -  if (TARGET_LL64 && !TARGET_HS)
> -    error ("-mll64 is only supported for ARC HS cores");
> -
> -  /* FPU support only for V2.  */
> -  if (TARGET_HARD_FLOAT)
> -    {
> -      if (TARGET_EM
> -	  && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
> -	error ("FPU double precision options are available for ARC HS only");
> -      if (TARGET_HS && (arc_fpu_build & FPX_DP))
> -	error ("FPU double precision assist "
> -	       "options are not available for ARC HS");
> -      if (!TARGET_HS && !TARGET_EM)
> -	error ("FPU options are available for ARCv2 architecture only");
> -    }
> -
>    arc_init_reg_tables ();
>  
>    /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
> @@ -853,7 +786,92 @@ static void
>  arc_override_options (void)
>  {
>    if (arc_cpu == PROCESSOR_NONE)
> -    arc_cpu = PROCESSOR_ARC700;
> +    arc_cpu = TARGET_CPU_DEFAULT;
> +
> +  /* Set the default cpu options.  */
> +  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
> +  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
> +
> +  /* Set the architectures.  */
> +  switch (arc_selected_arch->arch)
> +    {
> +    case BASE_ARCH_em:
> +      arc_arcem = true;
> +      arc_cpu_string = "EM";
> +      break;
> +    case BASE_ARCH_hs:
> +      arc_archs = true;
> +      arc_cpu_string = "HS";
> +      break;
> +    case BASE_ARCH_700:
> +      arc_arc700 = true;
> +      arc_cpu_string = "ARC700";
> +      break;
> +    case BASE_ARCH_6xx:
> +      arc_cpu_string = "ARC600";
> +      if (arc_selected_cpu->flags & FL_BS)
> +	arc_arc600 = true;
> +      else
> +	arc_arc601 = true;
> +      break;
> +    default:
> +      gcc_unreachable ();
> +    }
> +
> +  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
> +     specific flags are set in arc-common.c.  The architecture forces
> +     the default hardware configurations in, regardless what command
> +     line options are saying.  The CPU optional hw options can be
> +     turned on or off.  */
> +#define ARC_OPT(NAME, CODE, MASK, DOC)		\
> +  do {						\
> +    if ((arc_selected_cpu->flags & CODE)	\
> +	&& ((arc_seen_options & MASK) == 0))	\
> +      target_flags |= MASK;			\

I think replacing arc_seen_options with
'global_options_seeen.x_target_flags' achieves the same thing here.


> +    if (arc_selected_arch->dflags & CODE)	\
> +      target_flags |= MASK;			\
> +  } while (0);
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
> +  do {						\
> +    if ((arc_selected_cpu->flags & CODE)	\
> +	&& (VAR == DEFAULT_##VAR))		\
> +      VAR = VAL;				\
> +    if (arc_selected_arch->dflags & CODE)	\
> +      VAR = VAL;				\
> +  } while (0);
> +
> +#include "arc-options.def"
> +
> +#undef ARC_OPTX
> +#undef ARC_OPT
> +
> +  /* Check options against architecture options.  Throw an error if
> +     option is not allowed.  */
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
> +  do {								\
> +    if ((VAR == VAL)						\
> +	&& (!(arc_selected_arch->flags & CODE)))		\
> +      {								\
> +	error ("%s is not available for %s architecture",	\
> +	       DOC, arc_selected_arch->name);			\
> +      }								\
> +  } while (0);
> +#define ARC_OPT(NAME, CODE, MASK, DOC)				\
> +  do {								\
> +    if ((target_flags & MASK)					\
> +	&& (!(arc_selected_arch->flags & CODE)))		\
> +      error ("%s is not available for %s architecture",		\
> +	     DOC, arc_selected_arch->name);			\
> +  } while (0);
> +
> +#include "arc-options.def"
> +
> +#undef ARC_OPTX
> +#undef ARC_OPT
> +
> +  /* Set Tune option.  */
> +  if (arc_tune == TUNE_NONE)
> +    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
>  
>    if (arc_size_opt_level == 3)
>      optimize_size = 1;
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index c02e1cd..f1705d5 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_ARC_H
>  #define GCC_ARC_H
>  
> +#include <stdbool.h>
> +
>  /* Things to do:
>  
>     - incscc, decscc?
> @@ -39,6 +41,10 @@ along with GCC; see the file COPYING3.  If not see
>  #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
>  #define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
>  
> +#ifndef TARGET_CPU_DEFAULT
> +#define TARGET_CPU_DEFAULT	PROCESSOR_arc700
> +#endif
> +
>  /* Check if this symbol has a long_call attribute in its declaration */
>  #define SYMBOL_REF_LONG_CALL_P(X)	\
>  	((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
> @@ -74,9 +80,11 @@ along with GCC; see the file COPYING3.  If not see
>        GNU_USER_TARGET_OS_CPP_BUILTINS (); \
>      } \
>    while (0)
> -#endif
>  
> -/* Match the macros used in the assembler.  */
> +#endif /* DEFAULT_LIBC == LIBC_UCLIBC */
> +
> +/* Macros enabled by specific command line option.  FIXME: to be
> +   deprecatd.  */
>  #define CPP_SPEC "\
>  %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \
>  %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \
> @@ -85,34 +93,22 @@ along with GCC; see the file COPYING3.  If not see
>  %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \
>  %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \
>  %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \
> -%{mcpu=NPS400:-D__NPS400__} \
> -%{mcpu=nps400:-D__NPS400__} \
> -"
> +%{mcpu=nps400:-D__NPS400__}"
>  
>  #define CC1_SPEC "\
>  %{EB:%{EL:%emay not use both -EB and -EL}} \
>  %{EB:-mbig-endian} %{EL:-mlittle-endian} \
>  "
> +extern const char *arc_cpu_to_as (int argc, const char **argv);
> +
> +#define EXTRA_SPEC_FUNCTIONS			\
> +  { "cpu_to_as", arc_cpu_to_as },
> +
> +#define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "			\
> +  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
>  
> -#define ASM_DEFAULT "-mARC700 -mEA"
> -
> -#define ASM_SPEC  "\
> -%{mbig-endian|EB:-EB} %{EL} \
> -%{mcpu=ARC600:-mARC600} \
> -%{mcpu=ARC601:-mARC601} \
> -%{mcpu=ARC700:-mARC700} \
> -%{mcpu=ARC700:-mEA} \
> -%{!mcpu=*:" ASM_DEFAULT "} \
> -%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \
> -%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \
> -%{msimd} \
> -%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \
> -%{mcpu=ARC700|!mcpu=*:%{mlock}} \
> -%{mcpu=ARC700|!mcpu=*:%{mswape}} \
> -%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \
> -%{mcpu=ARCHS:-mHS} \
> -%{mcpu=ARCEM:-mEM} \
> -%{matomic:-mlock}"
> +#define OPTION_DEFAULT_SPECS						\
> +  {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
>  
>  #if DEFAULT_LIBC == LIBC_UCLIBC
>  /* Note that the default is to link against dynamic libraries, if they are
> @@ -196,17 +192,11 @@ along with GCC; see the file COPYING3.  If not see
>  #define TARGET_MMEDIUM_CALLS_DEFAULT 0
>  #endif
>  
> -#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \
> -  "%{mARC600|mA6: -mcpu=ARC600 %<mARC600 %<mA6}" \
> -  "%{mARC601: -mcpu=ARC601 %<mARC601}" \
> -  "%{mARC700|mA7: -mcpu=ARC700 %<mARC700 %<mA7}" \
> -  "%{mbarrel_shifte*: -mbarrel-shifte%* %<mbarrel_shifte*}" \
> -  "%{mEA: -mea %<mEA}" \
> -  "%{mspfp_*: -mspfp-%* %<mspfp_*}" \
> -  "%{mdpfp_*: -mdpfp-%* %<mdpfp_*}" \
> -  "%{mdsp_pack*: -mdsp-pack%* %<mdsp_pack*}" \
> -  "%{mmac_*: -mmac-%* %<mmac_*}" \
> -  "%{multcost=*: -mmultcost=%* %<multcost=*}"
> +#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS		   \
> +  "%{mARC600|mA6: -mcpu=arc600 %<mARC600 %<mA6 %<mARC600}"	   \
> +  "%{mARC601: -mcpu=arc601 %<mARC601}"				   \
> +  "%{mARC700|mA7: -mcpu=arc700 %<mARC700 %<mA7}"		   \
> +  "%{mEA: -mea %<mEA}"
>  
>  /* Run-time compilation parameters selecting different hardware subsets.  */
>  
> @@ -252,20 +242,23 @@ along with GCC; see the file COPYING3.  If not see
>     use conditional execution?  */
>  #define TARGET_AT_DBR_CONDEXEC  (!TARGET_ARC700 && !TARGET_V2)
>  
> -#define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
> -#define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
> -#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700	\
> -		       || arc_cpu == PROCESSOR_NPS400)
> -#define TARGET_EM     (arc_cpu == PROCESSOR_ARCEM)
> -#define TARGET_HS     (arc_cpu == PROCESSOR_ARCHS)
> -#define TARGET_V2							\
> -  ((arc_cpu == PROCESSOR_ARCHS) || (arc_cpu == PROCESSOR_ARCEM))
> -
> -/* Recast the cpu class to be the cpu attribute.  */
> -#define arc_cpu_attr ((enum attr_cpu)arc_cpu)
> -
> -#ifndef MULTILIB_DEFAULTS
> -#define MULTILIB_DEFAULTS { "mARC700" }
> +extern bool arc_arcem;
> +extern bool arc_archs;
> +extern bool arc_arc700;
> +extern bool arc_arc600;
> +extern bool arc_arc601;
> +
> +#define TARGET_ARC600 (arc_arc600)
> +#define TARGET_ARC601 (arc_arc601)
> +#define TARGET_ARC700 (arc_arc700)
> +#define TARGET_EM (arc_arcem)
> +#define TARGET_HS (arc_archs)
> +#define TARGET_V2 (TARGET_EM || TARGET_HS)

Can you expand a little on the motivation and benefits of switching
from one variable holding the cpu type to a set of independent flags?

Do you expect that multiple flags might be true at the same time?  I
would think the model of having a single enum variable would be more
obvious and simpler to maintain.

> +
> +#ifdef ARC_MULTILIB_CPU_DEFAULT
> +# ifndef MULTILIB_DEFAULTS
> +#  define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT }
> +# endif
>  #endif
>  
>  #ifndef UNALIGNED_ACCESS_DEFAULT
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index 715da31..6f757b6 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -231,11 +231,6 @@
>  	 (eq_attr "is_CALL" "yes") (const_string "yes")]
>  	(const_string "no")))
>  
> -
> -;; Attribute describing the processor
> -(define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
> -  (const (symbol_ref "arc_cpu_attr")))
> -
>  ;; true for compact instructions (those with _s suffix)
>  ;; "maybe" means compact unless we conditionalize the insn.
>  (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
> diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
> index 4caf366..1578549 100644
> --- a/gcc/config/arc/arc.opt
> +++ b/gcc/config/arc/arc.opt
> @@ -53,9 +53,12 @@ mARC700
>  Target Report
>  Same as -mA7.
>  
> +TargetVariable
> +int arc_mpy_option = DEFAULT_arc_mpy_option
> +
>  mmpy-option=
> -Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
> --mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
> +Target RejectNegative Joined
> +-mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
>  
>  mdiv-rem
>  Target Report Mask(DIVREM)
> @@ -100,7 +103,7 @@ Target Report Mask(MUL64_SET)
>  Generate mul64 and mulu64 instructions.
>  
>  mno-mpy
> -Target Report Mask(NOMPY_SET)
> +Target Report Mask(NOMPY_SET) Warn(%qs is deprecated)
>  Do not generate mpy instructions for ARC700.
>  
>  mea
> @@ -167,45 +170,6 @@ mcpu=
>  Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
>  -mcpu=CPU	Compile code for ARC variant CPU.
>  
> -Enum
> -Name(processor_type) Type(enum processor_type)
> -
> -EnumValue
> -Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
> -
> -EnumValue
> -Enum(processor_type) String(arc600) Value(PROCESSOR_ARC600)
> -
> -EnumValue
> -Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
> -
> -EnumValue
> -Enum(processor_type) String(arc601) Value(PROCESSOR_ARC601)
> -
> -EnumValue
> -Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
> -
> -EnumValue
> -Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700)
> -
> -EnumValue
> -Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400)
> -
> -EnumValue
> -Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400)
> -
> -EnumValue
> -Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM)
> -
> -EnumValue
> -Enum(processor_type) String(arcem) Value(PROCESSOR_ARCEM)
> -
> -EnumValue
> -Enum(processor_type) String(ARCHS) Value(PROCESSOR_ARCHS)
> -
> -EnumValue
> -Enum(processor_type) String(archs) Value(PROCESSOR_ARCHS)
> -
>  msize-level=
>  Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
>  size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os.
> @@ -308,25 +272,25 @@ Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
>  ; Flags used by the assembler, but for which we define preprocessor
>  ; macro symbols as well.
>  mcrc
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable variable polynomial CRC extension.
>  
>  mdsp-packa
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable DSP 3.1 Pack A extensions.
>  
>  mdvbf
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable dual viterbi butterfly extension.
>  
>  mmac-d16
> -Target Report Undocumented
> +Target Report Undocumented Warn(%qs is deprecated)
>  
>  mmac-24
> -Target Report Undocumented
> +Target Report Undocumented Warn(%qs is deprecated)
>  
>  mtelephony
> -Target Report RejectNegative
> +Target Report RejectNegative Warn(%qs is deprecated)
>  Enable Dual and Single Operand Instructions for Telephony.
>  
>  mxy
> @@ -343,7 +307,7 @@ Target Report
>  Enable swap byte ordering extension instruction.
>  
>  mrtsc
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable 64-bit Time-Stamp Counter extension instruction.
>  
>  EB
> @@ -394,24 +358,6 @@ Target
>  multcost=
>  Target RejectNegative Joined
>  
> -; Unfortunately, listing the full option name gives us clashes
> -; with OPT_opt_name being claimed for both opt_name and opt-name,
> -; so we leave out the last character or more.
> -mbarrel_shifte
> -Target Joined
> -
> -mspfp_
> -Target Joined
> -
> -mdpfp_
> -Target Joined
> -
> -mdsp_pack
> -Target Joined
> -
> -mmac_
> -Target Joined
> -
>  matomic
>  Target Report Mask(ATOMIC)
>  Enable atomic instructions.
> @@ -421,47 +367,47 @@ Target Report Mask(LL64)
>  Enable double load/store instructions for ARC HS.
>  
>  mfpu=
> -Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
> +Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(DEFAULT_arc_fpu_build)
>  Specify the name of the target floating point configuration.
>  
>  Enum
>  Name(arc_fpu) Type(int)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
> +Enum(arc_fpu) String(fpus) Value(FPU_FPUS)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
> +Enum(arc_fpu) String(fpud) Value(FPU_FPUD)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
> +Enum(arc_fpu) String(fpuda) Value(FPU_FPUDA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
> +Enum(arc_fpu) String(fpuda_div) Value(FPU_FPUDA_DIV)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
> +Enum(arc_fpu) String(fpuda_fma) Value(FPU_FPUDA_FMA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
> +Enum(arc_fpu) String(fpuda_all) Value(FPU_FPUDA_ALL)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
> +Enum(arc_fpu) String(fpus_div) Value(FPU_FPUS_DIV)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
> +Enum(arc_fpu) String(fpud_div) Value(FPU_FPUD_DIV)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
> +Enum(arc_fpu) String(fpus_fma) Value(FPU_FPUS_FMA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
> +Enum(arc_fpu) String(fpud_fma) Value(FPU_FPUD_FMA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
> +Enum(arc_fpu) String(fpus_all) Value(FPU_FPUS_ALL)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
> +Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL)
>  
>  mtp-regno=
>  Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25)
> @@ -481,3 +427,6 @@ Enable use of NPS400 xld/xst extension.
>  munaligned-access
>  Target Report Var(unaligned_access) Init(UNALIGNED_ACCESS_DEFAULT)
>  Enable unaligned word and halfword accesses to packed data.
> +
> +TargetVariable
> +unsigned int arc_seen_options = 0
> diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
> new file mode 100644
> index 0000000..c51b708
> --- /dev/null
> +++ b/gcc/config/arc/driver-arc.c
> @@ -0,0 +1,80 @@
> +/* Subroutines for the gcc driver.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +   Contributed by Claudiu Zissulescu <claziss@synopsys.com>
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3, or (at your option)
> +   any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "tm.h"
> +
> +/* Returns command line parameters to pass to as.  */
> +
> +const char*
> +arc_cpu_to_as (int argc, const char **argv)
> +{
> +  const char *name = NULL;
> +  const arc_cpu_t *arc_selected_cpu;
> +
> +  /* No argument, check what is the default cpu.  */
> +  if (argc == 0)
> +    {
> +      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
> +    }
> +  else
> +    {
> +      name = argv[0];
> +      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
> +	   arc_selected_cpu++)
> +	{
> +	  if (strcmp (arc_selected_cpu->name, name) == 0)
> +	    break;
> +	}
> +    }
> +
> +  /* Checking the flags is only required with the old binutils
> +     tools.  */

I don't understand what this comment is telling me.

> +  switch (arc_selected_cpu->arch)
> +    {
> +    case BASE_ARCH_em:
> +      if (arc_selected_cpu->flags & FL_CD)
> +	name = "-mcode-density";
> +      else
> +	name = "";
> +      if (arc_selected_cpu->flags & FL_FPUDA)
> +	name = concat ("-mfpuda ", name, NULL);
> +      if (arc_selected_cpu->flags & FL_SPFP)
> +	name = concat ("-mspfp ", name, NULL);
> +      if (arc_selected_cpu->flags & FL_DPFP)
> +	name = concat ("-mdpfp ", name, NULL);
> +      return concat ("-mcpu=arcem ", name, NULL);
> +    case BASE_ARCH_hs:
> +      return "-mcpu=archs";
> +    case BASE_ARCH_700:
> +      return "-mcpu=arc700 -mEA";
> +    case BASE_ARCH_6xx:
> +      if (arc_selected_cpu->flags & FL_MUL64)
> +	return "-mcpu=arc600 -mmul64 -mnorm";
> +      if (arc_selected_cpu->flags & FL_MUL32x16)
> +	return "-mcpu=arc600 -mdsp-packa -mnorm";
> +      return "-mcpu=arc600 -mnorm";
> +    default:
> +      gcc_unreachable ();
> +    }
> +  return NULL;
> +}
> diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
> new file mode 100644
> index 0000000..5934f4f
> --- /dev/null
> +++ b/gcc/config/arc/genmultilib.awk
> @@ -0,0 +1,203 @@
> +# Copyright (C) 2016 Free Software Foundation, Inc.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 3, or (at your option) any later
> +# version.
> +#
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +# for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +##################################################################
> +#
> +# This file is using AVR's genmultilib.awk idea.
> +# Transform CPU Information from arc-cpu.def to a
> +# Representation that is understood by GCC's multilib Machinery.
> +#
> +# The Script works as a Filter from STDIN to STDOUT.
> +#
> +# FORMAT = "Makefile": Generate Makefile Snipet that sets some
> +#                      MULTILIB_* Variables as needed.
> +#
> +##################################################################
> +
> +BEGIN {
> +  FS ="[(, \t)]+"
> +  comment = 1
> +  n_cores = 0
> +  n_reuse = 0
> +}
> +
> +##################################################################
> +# Add some Comments to the generated Files and copy-paste
> +# Copyright Notice from above.
> +##################################################################
> +/^#/ {
> +  if (!comment)
> +    next
> +  else if (comment == 1)
> +    {
> +      if (FORMAT == "Makefile")
> +	{
> +	  print "# Auto-generated Makefile Snip"
> +	  print "# Generated by    : ./gcc/config/arc/genmultilib.awk"
> +	  print "# Generated from  : ./gcc/config/arc/arc-cpu.def"
> +	  print "# Used by         : tmake_file from Makefile and genmultilib"
> +	  print ""
> +	}
> +    }
> +
> +  comment = 2;
> +
> +  print
> +}
> +
> +/^$/ {
> +  # The first empty line stops copy-pasting the GPL comments
> +  # from this file to the generated file.
> +
> +  comment = 0
> +}
> +
> +
> +/^ARC_CPU/ {
> +  name = $2
> +  #  gsub ("\"", "", name)
> +
> +  if ($4 != "0")
> +    {
> +      arch = $3
> +      if (arch == "6xx")
> +	arch = 601
> +
> +      n = split ($4, cpu_flg, "|")
> +
> +      line = "mcpu." arch
> +      for (i = 1; i <= n; i++)
> +	{
> +	  if (cpu_flg[i] == "FL_MPYOPT_0")
> +	    line = line "/mmpy-option.0"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_1")
> +	    line = line "/mmpy-option.1"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_2")
> +	    line = line "/mmpy-option.2"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_3")
> +	    line = line "/mmpy-option.3"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_4")
> +	    line = line "/mmpy-option.4"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_5")
> +	    line = line "/mmpy-option.5"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_6")
> +	    line = line "/mmpy-option.6"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_7")
> +	    line = line "/mmpy-option.7"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_8")
> +	    line = line "/mmpy-option.8"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_9")
> +	    line = line "/mmpy-option.9"
> +	  else if (cpu_flg[i] == "FL_CD")
> +	    line = line "/mcode-density"
> +	  else if (cpu_flg[i] == "FL_BS")
> +	    line = line "/mbarrel-shifter"
> +	  else if (cpu_flg[i] == "FL_DIVREM")
> +	    line = line "/mdiv-rem"
> +	  else if (cpu_flg[i] == "FL_NORM" \
> +		   || cpu_flg[i] == "FL_SWAP")
> +	    line = line "/mnorm"
> +	  else if (cpu_flg[i] == "FL_FPU_FPUS")
> +	    line = line "/mfpu.fpus"
> +	  else if (cpu_flg[i] == "FL_FPU_FPUDA")
> +	    line = line "/mfpu.fpuda"
> +	  else if (cpu_flg[i] == "FL_FPU_FPUD_ALL")
> +	    line = line "/mfpu.fpud_all"
> +	  else if (cpu_flg[i] == "FL_LL64")
> +	    line = line "/mll64"
> +	  else if (cpu_flg[i] == "FL_MUL64")
> +	    line = line "/mmul64"
> +	  else if (cpu_flg[i] == "FL_MUL32x16")
> +	    line = line "/mmul32x16"
> +	  else if (cpu_flg[i] == "FL_FPX_QUARK")
> +	    line = line "/quark"
> +	  else if (cpu_flg[i] == "FL_SPFP")
> +	    line = line "/spfp"
> +	  else if (cpu_flg[i] == "FL_DPFP")
> +	    line = line "/dpfp"
> +	  else
> +	    {
> +	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
> +	      exit 1
> +	    }
> +	}
> +      line = "mcpu." name "=" line
> +      reuse[n_reuse] = line
> +      n_reuse++
> +    }
> +
> +  core = name
> +  cores[n_cores] = core
> +  n_cores++
> +}
> +
> +##################################################################
> +#
> +# We gathered all the Information, now build/output the following:
> +#
> +#    awk Variable         target Variable          FORMAT
> +#  -----------------------------------------------------------
> +#    m_options     <->    MULTILIB_OPTIONS         Makefile
> +#    m_dirnames    <->    MULTILIB_DIRNAMES           "
> +#
> +##################################################################
> +
> +END {
> +  m_options    = "\nMULTILIB_OPTIONS = "
> +  m_dirnames   = "\nMULTILIB_DIRNAMES ="
> +  m_reuse      = "\nMULTILIB_REUSE ="
> +
> +  sep = ""
> +  for (c = 0; c < n_cores; c++)
> +    {
> +      m_options  = m_options sep "mcpu=" cores[c]
> +      m_dirnames = m_dirnames " " cores[c]
> +      sep = "/"
> +    }
> +
> +  sep = ""
> +  for (c = 0; c < n_reuse; c++)
> +    {
> +      m_reuse = m_reuse sep reuse[c]
> +      sep = "\nMULTILIB_REUSE +="
> +    }
> +  ############################################################
> +  # Output that Stuff
> +  ############################################################
> +
> +  if (FORMAT == "Makefile")
> +    {
> +      # Intended Target: ./gcc/config/arc/t-multilib
> +
> +      print m_options
> +      print m_dirnames
> +
> +      ############################################################
> +      # Legacy Aliases
> +      ############################################################
> +
> +      print ""
> +      print "# Aliases:"
> +      print "MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600"
> +      print "MULTILIB_MATCHES += mcpu?arc600=mARC600"
> +      print "MULTILIB_MATCHES += mcpu?arc600=mA6"
> +      print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601"
> +      print "MULTILIB_MATCHES += mcpu?arc700=mA7"
> +      print "MULTILIB_MATCHES += mcpu?arc700=mARC700"
> +    }
> +}
> diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk
> new file mode 100644
> index 0000000..24a93eb
> --- /dev/null
> +++ b/gcc/config/arc/genoptions.awk
> @@ -0,0 +1,86 @@
> +# Copyright (C) 2016 Free Software Foundation, Inc.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 3, or (at your option) any later
> +# version.
> +#
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +# for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +##################################################################
> +#
> +# This file is using AVR's genmultilib.awk idea.
> +#
> +##################################################################
> +
> +BEGIN {
> +  FS ="[(, \t)]+"
> +  comment = 1
> +  n_cores = 0
> +}
> +
> +##################################################################
> +# Add some Comments to the generated Files and copy-paste
> +# Copyright Notice from above.
> +##################################################################
> +/^#/ {
> +  if (!comment)
> +    next
> +  else if (comment == 1)
> +    {
> +      if (FORMAT == "Makefile")
> +	{
> +	  print "; Auto-generated Makefile Snip"
> +	  print "; Generated by    : ./gcc/config/arc/genoptions.awk"
> +	  print "; Generated from  : ./gcc/config/arc/arc-cpu.def"
> +	  print ";"
> +	}
> +    }
> +
> +  comment = 2;
> +
> +  gsub ("^#", ";", $0)
> +  print
> +}
> +
> +/^$/ {
> +    # The first empty line stops copy-pasting the GPL comments
> +    # from this file to the generated file.
> +    comment = 0
> +}
> +
> +/^ARC_CPU/ {
> +  name = $2
> +  cores[n_cores] = name;
> +  n_cores++
> +}
> +
> +END {
> +  m_option = ""
> +  for (c = 0; c < n_cores; c++)
> +    {
> +      m_options = m_options "EnumValue\nEnum(processor_type) String(" \
> +	cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n"
> +    }
> +
> +  ############################################################
> +  # Output that Stuff
> +  ############################################################
> +
> +  if (FORMAT == "Makefile")
> +    {
> +	print "\nEnum"
> +	print "Name(processor_type) Type(enum processor_type)"
> +	print "Known ARC CPUs (for use with the -mcpu= option):\n"
> +	print m_options
> +    }
> +}
> diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
> index 4252e73..bdb1328 100644
> --- a/gcc/config/arc/t-arc
> +++ b/gcc/config/arc/t-arc
> @@ -19,11 +19,30 @@
>  
>  TM_H += $(srcdir)/config/arc/arc-c.def
>  
> +driver-arc.o: $(srcdir)/config/arc/driver-arc.c \
> +  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
> +	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
> +
>  arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \
>  $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
>  	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
>  		$(srcdir)/config/arc/arc-c.c
>  
> +#Run `arc-cpus` if you changed something in arc-cpus.def
> +
> +.PHONY: arc-cpus
> +
> +arc-cpus: $(srcdir)/config/arc/t-multilib \
> +	$(srcdir)/config/arc/arc-tables.opt
> +
> +$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk 	\
> +				 $(srcdir)/config/arc/arc-cpus.def
> +	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
> +
> +$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \
> +				 $(srcdir)/config/arc/arc-cpus.def
> +	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
> +
>  # Local Variables:
>  # mode: Makefile
>  # End:
> diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib
> deleted file mode 100644
> index c49a3fcc..0000000
> --- a/gcc/config/arc/t-arc-newlib
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
> -
> -# Copyright (C) 2007-2016 Free Software Foundation, Inc.
> -
> -# This file is part of GCC.
> -
> -# GCC is free software; you can redistribute it and/or modify it under the
> -# terms of the GNU General Public License as published by the Free Software
> -# Foundation; either version 3, or (at your option) any later version.
> -
> -# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
> -# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
> -# details.
> -
> -# You should have received a copy of the GNU General Public License along
> -# with GCC; see the file COPYING3.  If not see
> -# <http://www.gnu.org/licenses/>.
> -
> -MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm
> -MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm
> -#
> -# Aliases:
> -MULTILIB_MATCHES  = mcpu?ARC600=mcpu?arc600
> -MULTILIB_MATCHES += mcpu?ARC600=mARC600
> -MULTILIB_MATCHES += mcpu?ARC600=mA6
> -MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
> -MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
> -MULTILIB_MATCHES += mcpu?ARC700=mA7
> -MULTILIB_MATCHES += mcpu?ARC700=mARC700
> -MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700
> -MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem
> -MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs
> -MULTILIB_MATCHES += EL=mlittle-endian
> -MULTILIB_MATCHES += EB=mbig-endian
> -#
> -# These don't make sense for the ARC700 default target:
> -MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm*
> -# And neither of the -mmul* options make sense without -mnorm:
> -MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
> -# Exclusions for ARC700
> -MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16*
> -# Exclusions for ARCv2EM
> -MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16*
> -# Exclusions for ARCv2HS
> -MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm*
> diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-arc-uClibc
> deleted file mode 100644
> index 11e81f1..0000000
> --- a/gcc/config/arc/t-arc-uClibc
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
> -
> -# Copyright (C) 2007-2016 Free Software Foundation, Inc.
> -
> -# This file is part of GCC.
> -
> -# GCC is free software; you can redistribute it and/or modify it under the
> -# terms of the GNU General Public License as published by the Free Software
> -# Foundation; either version 3, or (at your option) any later version.
> -
> -# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
> -# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
> -# details.
> -
> -# You should have received a copy of the GNU General Public License along
> -# with GCC; see the file COPYING3.  If not see
> -# <http://www.gnu.org/licenses/>.
> -
> -MULTILIB_EXTRA_OPTS = mno-sdata
> diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
> new file mode 100644
> index 0000000..5a36af6
> --- /dev/null
> +++ b/gcc/config/arc/t-multilib
> @@ -0,0 +1,34 @@
> +# Auto-generated Makefile Snip
> +# Generated by    : ./gcc/config/arc/genmultilib.awk
> +# Generated from  : ./gcc/config/arc/arc-cpu.def
> +# Used by         : tmake_file from Makefile and genmultilib
> +
> +# Copyright (C) 2016 Free Software Foundation, Inc.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 3, or (at your option) any later
> +# version.
> +#
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +# for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
> +
> +MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
> +
> +# Aliases:
> +MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
> +MULTILIB_MATCHES += mcpu?arc600=mARC600
> +MULTILIB_MATCHES += mcpu?arc600=mA6
> +MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601
> +MULTILIB_MATCHES += mcpu?arc700=mA7
> +MULTILIB_MATCHES += mcpu?arc700=mARC700
> diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc
> new file mode 100644
> index 0000000..11e81f1
> --- /dev/null
> +++ b/gcc/config/arc/t-uClibc
> @@ -0,0 +1,20 @@
> +# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
> +
> +# Copyright (C) 2007-2016 Free Software Foundation, Inc.
> +
> +# This file is part of GCC.
> +
> +# GCC is free software; you can redistribute it and/or modify it under the
> +# terms of the GNU General Public License as published by the Free Software
> +# Foundation; either version 3, or (at your option) any later version.
> +
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
> +# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
> +# details.
> +
> +# You should have received a copy of the GNU General Public License along
> +# with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +MULTILIB_EXTRA_OPTS = mno-sdata
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 3f9c0a0..4399733 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -13882,29 +13882,92 @@ values for @var{cpu} are
>  @table @samp
>  @opindex mA6
>  @opindex mARC600
> -@item ARC600
>  @item arc600
>  Compile for ARC600.  Aliases: @option{-mA6}, @option{-mARC600}.
>  
> -@item ARC601
>  @item arc601
>  @opindex mARC601
>  Compile for ARC601.  Alias: @option{-mARC601}.
>  
> -@item ARC700
>  @item arc700
>  @opindex mA7
>  @opindex mARC700
>  Compile for ARC700.  Aliases: @option{-mA7}, @option{-mARC700}.
>  This is the default when configured with @option{--with-cpu=arc700}@.
>  
> -@item ARCEM
>  @item arcem
>  Compile for ARC EM.
>  
> -@item ARCHS
>  @item archs
>  Compile for ARC HS.
> +
> +@item em
> +@opindex em
> +Compile for ARC EM cpu with no hardware extension.
> +
> +@item em4
> +@opindex em4
> +Compile for ARC EM4 cpu.
> +
> +@item em4_dmips
> +@opindex em4_dmips
> +Compile for ARC EM4 DMIPS cpu.
> +
> +@item em4_fpus
> +@opindex em4_fpus
> +Compile for ARC EM4 DMIPS cpu with single precision floating point
> +extension.
> +
> +@item em4_fpuda
> +@opindex em4_fpuda
> +Compile for ARC EM4 DMIPS cpu with single precision floating point and
> +double assists instructions.
> +
> +@item hs
> +@opindex hs
> +Compile for ARC HS cpu with no hardware extension, except the atomic
> +instructions.
> +
> +@item hs34
> +@opindex hs34
> +Compile for ARC HS34 cpu.
> +
> +@item hs38
> +@opindex hs38
> +Compile for ARC HS38 cpu.
> +
> +@item hs38_linux
> +@opindex hs38_linux
> +Compile for ARC HS38 cpu with all hardware extensions on.
> +
> +@item arc600_norm
> +@opindex arc600_norm
> +Compile for ARC 600 cpu with norm instruction enabled.
> +
> +@item arc600_mul32x16
> +@opindex arc600_mul32x16
> +Compile for ARC 600 cpu with norm and mul32x16 instructions enabled.
> +
> +@item arc600_mul64
> +@opindex arc600_mul64
> +Compile for ARC 600 cpu with norm and mul64 instructions enabled.
> +
> +@item arc601_norm
> +@opindex arc601_norm
> +Compile for ARC 601 cpu with norm instruction enabled.
> +
> +@item arc601_mul32x16
> +@opindex arc601_mul32x16
> +Compile for ARC 601 cpu with norm and mul32x16 instructions enabled.
> +
> +@item arc601_mul64
> +@opindex arc601_mul64
> +Compile for ARC 601 cpu with norm and mul64 instructions enabled.
> +
> +@item nps400
> +@opindex nps400
> +Compile for ARC 700 on NPS400 chip.
> +
>  @end table
>  
>  @item -mdpfp
> @@ -13931,7 +13994,8 @@ supported.  This is always enabled for @option{-mcpu=ARC700}.
>  
>  @item -mno-mpy
>  @opindex mno-mpy
> -Do not generate mpy instructions for ARC700.
> +Do not generate mpy instructions for ARC700.  This instruction is
> +deprecated.
>  
>  @item -mmul32x16
>  @opindex mmul32x16
> @@ -14138,12 +14202,14 @@ define preprocessor macro symbols.
>  @item -mdsp-packa
>  @opindex mdsp-packa
>  Passed down to the assembler to enable the DSP Pack A extensions.
> -Also sets the preprocessor symbol @code{__Xdsp_packa}.
> +Also sets the preprocessor symbol @code{__Xdsp_packa}.  This option is
> +deprecated.
>  
>  @item -mdvbf
>  @opindex mdvbf
>  Passed down to the assembler to enable the dual viterbi butterfly
> -extension.  Also sets the preprocessor symbol @code{__Xdvbf}.
> +extension.  Also sets the preprocessor symbol @code{__Xdvbf}.  This
> +option is deprecated.
>  
>  @c ARC700 4.10 extension instruction
>  @item -mlock
> @@ -14155,19 +14221,19 @@ Conditional extension.  Also sets the preprocessor symbol
>  @item -mmac-d16
>  @opindex mmac-d16
>  Passed down to the assembler.  Also sets the preprocessor symbol
> -@code{__Xxmac_d16}.
> +@code{__Xxmac_d16}.  This option is deprecated.
>  
>  @item -mmac-24
>  @opindex mmac-24
>  Passed down to the assembler.  Also sets the preprocessor symbol
> -@code{__Xxmac_24}.
> +@code{__Xxmac_24}.  This option is deprecated.
>  
>  @c ARC700 4.10 extension instruction
>  @item -mrtsc
>  @opindex mrtsc
>  Passed down to the assembler to enable the 64-bit Time-Stamp Counter
>  extension instruction.  Also sets the preprocessor symbol
> -@code{__Xrtsc}.
> +@code{__Xrtsc}.  This option is deprecated.
>  
>  @c ARC700 4.10 extension instruction
>  @item -mswape
> @@ -14180,7 +14246,7 @@ extension instruction.  Also sets the preprocessor symbol
>  @opindex mtelephony
>  Passed down to the assembler to enable dual and single operand
>  instructions for telephony.  Also sets the preprocessor symbol
> -@code{__Xtelephony}.
> +@code{__Xtelephony}.  This option is deprecated.
>  
>  @item -mxy
>  @opindex mxy
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-10-12 20:02     ` Andrew Burgess
@ 2016-10-13  8:42       ` Claudiu Zissulescu
  2016-10-31 15:48       ` Claudiu Zissulescu
  1 sibling, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-10-13  8:42 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, Francois.Bedard

Hi Andrew,

> Sorry it's taken soooo long to review this patch.
> 
This is understandable, it is a quite large patch and changes a lot of items.

> In general I like this, and think it's a step in the right direction.
> I have a few pretty minor concerns, but hopefully nothing too
> contentious.
> 
> In general I like the use of the *.def files, but my only concern is
> the lack of explanation in any of them about what they're for.  It
> would be nice if each had a summary of what each field represents to
> make it easier to add new entries.

This is a good point, I will add extra info on how to add new entries.

> 
> The use of arc_seen_options can, I think be replaced by using
> global_opts_seen.x_target_flags, or maybe there's a detail I'm not
> understanding, in which case maybe a comment somewhere to explain why
> those two things are different.

I cannot remember why I haven't use the global_options_set, but I will try as u suggested.

> 
> The only thing I dislike in this patch is the switch from 'arc_cpu' to
> a set of global boolean flags.  I can't see why we'd ever want more
> than one of those architecture flags to be true, so I'd rather we
> switched back to an enum if that's possible.
> 
I remember, initially I wanted to use enums, but I bumped into an issue, don't remember exactly what.  As far as I can see now, it perfectly make sense your comment. 

I will come back to u with extra info/revised patch asap,
Claudiu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-10-12 20:02     ` Andrew Burgess
  2016-10-13  8:42       ` Claudiu Zissulescu
@ 2016-10-31 15:48       ` Claudiu Zissulescu
  2016-11-03 22:59         ` Andrew Burgess
  1 sibling, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-10-31 15:48 UTC (permalink / raw)
  To: gcc-patches, andrew.burgess; +Cc: Claudiu.Zissulescu, Francois.Bedard

Hi Andrew,

Please find the updated patch.

What is new:
- The .def files are having a comment block on how to add new lines.
- The arc_seen_option is not used.
- The arc_cpu* variables are not used.

Please let me know if I miss something,
Claudiu

gcc/
2016-05-09  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-arch.h: New file.
	* config/arc/arc-arches.def: Likewise.
	* config/arc/arc-cpus.def: Likewise.
	* config/arc/arc-options.def: Likewise.
	* config/arc/t-multilib: Likewise.
	* config/arc/genmultilib.awk: Likewise.
	* config/arc/genoptions.awk: Likewise.
	* config/arc/arc-tables.opt: Likewise.
	* config/arc/driver-arc.c: Likewise.
	* common/config/arc/arc-common.c (arc_handle_option): Trace
	toggled options.
	* config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra
	options; check for supported cpu against arc-cpus.def file.
	(arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define
	TARGET_CPU_BUILD macro; add driver-arc.o as an extra object.
	* config/arc/arc-c.def: Add emacs local variables.
	* config/arc/arc-opts.h (processor_type): Use arc-cpus.def file.
	(FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA)
	(FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL)
	(FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines.
	(DEFAULT_arc_fpu_build): Define.
	(DEFAULT_arc_mpy_option): Define.
	* config/arc/arc-protos.h (arc_init): Delete.
	* config/arc/arc.c (arc_cpu_name): New variable.
	(arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs)
	(arc_arc700, arc_arc600, arc_arc601): New variable.
	(arc_init): Add static; remove selection of default tune value,
	cleanup obsolete error messages.
	(arc_override_options): Make use of .def files for selecting the
	right cpu and option configurations.
	* config/arc/arc.h (stdbool.h): Include.
	(TARGET_CPU_DEFAULT): Define.
	(CPP_SPEC): Remove mcpu=NPS400 handling.
	(arc_cpu_to_as): Declare.
	(EXTRA_SPEC_FUNCTIONS): Define.
	(OPTION_DEFAULT_SPECS): Likewise.
	(ASM_DEFAULT): Remove.
	(ASM_SPEC): Use arc_cpu_to_as.
	(DRIVER_SELF_SPECS): Remove deprecated options.
	(arc_base_cpu):	Declare.
	(TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM)
	(TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_base_cpu
	variable.
	(MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT.
	* config/arc/arc.md (attr_cpu): Remove.
	* config/arc/arc.opt (arc_mpy_option): Make it target variable.
	(mno-mpy): Deprecate.
	(mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM)
	(mcpu=ARCHS): Remove.
	(mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc):
	Deprecate.
	(mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove.
	(arc_fpu): Use new defines.
	(arc_seen_options): New target variable.
	* config/arc/t-arc (driver-arc.o): New target.
	(arc-cpus, t-multilib, arc-tables.opt): Likewise.
	* config/arc/t-arc-newlib: Delete.
	* config/arc/t-arc-uClibc: Renamed to t-uClibc.
	* doc/invoke.texi (ARC): Update arc options.
---
 gcc/common/config/arc/arc-common.c | 102 ++++++++++---------
 gcc/config.gcc                     |  47 +++++----
 gcc/config/arc/arc-arch.h          | 120 ++++++++++++++++++++++
 gcc/config/arc/arc-arches.def      |  56 ++++++++++
 gcc/config/arc/arc-c.def           |   4 +
 gcc/config/arc/arc-cpus.def        |  75 ++++++++++++++
 gcc/config/arc/arc-options.def     | 109 ++++++++++++++++++++
 gcc/config/arc/arc-opts.h          |  47 +++++++--
 gcc/config/arc/arc-protos.h        |   1 -
 gcc/config/arc/arc-tables.opt      |  90 ++++++++++++++++
 gcc/config/arc/arc.c               | 176 +++++++++++++++++---------------
 gcc/config/arc/arc.h               |  89 ++++++++--------
 gcc/config/arc/arc.md              |   5 -
 gcc/config/arc/arc.opt             | 106 +++++--------------
 gcc/config/arc/driver-arc.c        |  78 ++++++++++++++
 gcc/config/arc/genmultilib.awk     | 203 +++++++++++++++++++++++++++++++++++++
 gcc/config/arc/genoptions.awk      |  86 ++++++++++++++++
 gcc/config/arc/t-arc               |  19 ++++
 gcc/config/arc/t-arc-newlib        |  46 ---------
 gcc/config/arc/t-arc-uClibc        |  20 ----
 gcc/config/arc/t-multilib          |  34 +++++++
 gcc/config/arc/t-uClibc            |  20 ++++
 gcc/doc/invoke.texi                |  90 +++++++++++++---
 23 files changed, 1247 insertions(+), 376 deletions(-)
 create mode 100644 gcc/config/arc/arc-arch.h
 create mode 100644 gcc/config/arc/arc-arches.def
 create mode 100644 gcc/config/arc/arc-cpus.def
 create mode 100644 gcc/config/arc/arc-options.def
 create mode 100644 gcc/config/arc/arc-tables.opt
 create mode 100644 gcc/config/arc/driver-arc.c
 create mode 100644 gcc/config/arc/genmultilib.awk
 create mode 100644 gcc/config/arc/genoptions.awk
 delete mode 100644 gcc/config/arc/t-arc-newlib
 delete mode 100644 gcc/config/arc/t-arc-uClibc
 create mode 100644 gcc/config/arc/t-multilib
 create mode 100644 gcc/config/arc/t-uClibc

diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index 5b687fb..bc97411 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -2,6 +2,7 @@
    Copyright (C) 1994-2016 Free Software Foundation, Inc.
    Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
 		on behalf of Synopsys Inc.
+		Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
 
 This file is part of GCC.
 
@@ -61,17 +62,19 @@ static const struct default_options arc_option_optimization_table[] =
 
 /*  Process options.  */
 static bool
-arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
+arc_handle_option (struct gcc_options *opts,
+		   struct gcc_options *opts_set ATTRIBUTE_UNUSED,
 		   const struct cl_decoded_option *decoded,
 		   location_t loc)
 {
   size_t code = decoded->opt_index;
   int value = decoded->value;
   const char *arg = decoded->arg;
+  static int mcpu_seen = PROCESSOR_NONE;
+  char *p;
 
   switch (code)
     {
-      static int mcpu_seen = PROCESSOR_NONE;
     case OPT_mcpu_:
       /* N.B., at this point arc_cpu has already been set to its new value by
 	 our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless.  */
@@ -79,71 +82,70 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
       if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
 	warning_at (loc, 0, "multiple -mcpu= options specified.");
       mcpu_seen = value;
+      break;
+
+    case OPT_mmpy_option_:
+      p = ASTRDUP (arg);
 
-      switch (value)
+      if (!strcmp (p, "0")
+	  || !strcmp (p, "none"))
+	opts->x_arc_mpy_option = 0;
+      else if (!strcmp (p, "1")
+	  || !strcmp (p, "w"))
 	{
-	case PROCESSOR_NPS400:
-	  if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) )
-	    opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1;
-	  /* Fall through */
-	case PROCESSOR_ARC600:
-	case PROCESSOR_ARC700:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARC601:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARCHS:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags |= MASK_CODE_DENSITY;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags |= MASK_NORM_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags |= MASK_SWAP_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags |= MASK_DIVREM;	  /* Default: on.  */
-	  break;
-
-	case PROCESSOR_ARCEM:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags &= ~MASK_CODE_DENSITY;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags &= ~MASK_NORM_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags &= ~MASK_SWAP_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags &= ~MASK_DIVREM;	  /* Default: off.  */
-	  break;
-	default:
-	  gcc_unreachable ();
+	  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);
+
       break;
 
-    case OPT_mmpy_option_:
-      if (value < 0 || value > 9)
-	error_at (loc, "bad value %qs for -mmpy-option switch", arg);
+    default:
       break;
     }
 
   return true;
 }
 
+#undef  TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
+
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
 #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
-#define TARGET_HANDLE_OPTION arc_handle_option
 
 #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
 
-/* We default to ARC700, which has the barrel shifter enabled.  */
-#define TARGET_DEFAULT_TARGET_FLAGS \
-  (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET)
 
+#undef  TARGET_HANDLE_OPTION
+#define TARGET_HANDLE_OPTION arc_handle_option
 
 #include "common/common-target-def.h"
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 8fd07c5..50dca89 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -318,6 +318,7 @@ arc*-*-*)
 	cpu_type=arc
 	c_target_objs="arc-c.o"
 	cxx_target_objs="arc-c.o"
+	extra_options="${extra_options} arc/arc-tables.opt"
 	;;
 arm*-*-*)
 	cpu_type=arm
@@ -991,13 +992,12 @@ alpha*-dec-*vms*)
 	;;
 arc*-*-elf*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
-	tmake_file="arc/t-arc-newlib arc/t-arc"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
+	tmake_file="arc/t-multilib arc/t-arc"
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -1014,15 +1014,14 @@ arc*-*-elf*)
 	;;
 arc*-*-linux-uclibc*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
-	tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc"
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
+	tmake_file="${tmake_file} arc/t-uClibc arc/t-arc"
 	tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0"
 	tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -3605,15 +3604,19 @@ case "${target}" in
 		done
 		;;
 
-	arc*-*-*) # was:	arc*-*-linux-uclibc)
+	arc*-*-*)
 		supported_defaults="cpu"
-		case $with_cpu in
-		  arc600|arc601|arc700)
-			;;
-		  *) echo "Unknown cpu type"
-			exit 1
-			;;
-		esac
+
+		if [ x"$with_cpu" = x ] \
+		    || grep "^ARC_CPU ($with_cpu," \
+		       ${srcdir}/config/arc/arc-cpus.def \
+		       > /dev/null; then
+		 # Ok
+		 true
+		else
+		 echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
+		 exit 1
+		fi
 		;;
 
 	arm*-*-*)
diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
new file mode 100644
index 0000000..7994543
--- /dev/null
+++ b/gcc/config/arc/arc-arch.h
@@ -0,0 +1,120 @@
+/* Definitions of types that are used to store ARC architecture and
+   device information.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu (claziss@synopsys.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ARC_ARCH_H
+#define GCC_ARC_ARCH_H
+
+#ifndef IN_LIBGCC2
+/* Architecture selection types.  */
+
+enum cpu_flags
+  {
+#define ARC_OPT(NAME, CODE, MASK, DOC)	    NAME = CODE,
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE,
+#include "arc-options.def"
+#undef ARC_OPT
+#undef ARC_OPTX
+    FL_END
+  };
+
+
+/* ARC architecture variants.  */
+
+enum base_architecture
+  {
+    BASE_ARCH_NONE,
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)  BASE_ARCH_##ARCH,
+#include "arc-arches.def"
+#undef ARC_ARCH
+    BASE_ARCH_END
+  };
+
+
+/* Tune variants.  Needs to match the attr_tune enum.  */
+
+enum arc_tune_attr
+  {
+    ARC_TUNE_NONE,
+    ARC_TUNE_ARC600,
+    ARC_TUNE_ARC700_4_2_STD,
+    ARC_TUNE_ARC700_4_2_XMAC
+  };
+
+/* CPU specific properties.  */
+
+typedef struct
+{
+  /* CPU name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* Specific flags.  */
+  const unsigned long long flags;
+
+  /* Tune value.  */
+  enum arc_tune_attr tune;
+} arc_cpu_t;
+
+
+/* Architecture specific propoerties.  */
+
+typedef struct
+{
+  /* Architecture name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* All allowed flags for this architecture.  */
+  const unsigned long long flags;
+
+  /* Default flags for this architecture.  It is a subset of
+     FLAGS.  */
+  const unsigned long long dflags;
+} arc_arch_t;
+
+
+
+const arc_arch_t arc_arch_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, 0},
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)	\
+    {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS},
+#include "arc-arches.def"
+#undef ARC_ARCH
+    {NULL, BASE_ARCH_END, 0, 0}
+  };
+
+const arc_cpu_t arc_cpu_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE},
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
+    {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE},
+#include "arc-cpus.def"
+#undef ARC_CPU
+    {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE}
+  };
+
+#endif
+#endif /* GCC_ARC_ARCH_H */
diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
new file mode 100644
index 0000000..f24babb
--- /dev/null
+++ b/gcc/config/arc/arc-arches.def
@@ -0,0 +1,56 @@
+/* ARC ARCH architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of all known ARC base architectures.  These defines are used
+   to check if command line given options are valid for a specific
+   architecture, and to set default architecture options, if needed.
+
+   Before including this file, define a macro:
+
+   ARC_ARCH (NAME, ARCH, DEV_HW_FACILITIES, DEF_HW_FACILITIES)
+
+   where the arguments are the fields of arc_arch_t:
+
+   NAME			Architecture given name;
+
+   ARCH			Architecture class as in enum base_architecture;
+
+   DEV_HW_FACILITIES	All allowed architecture hardware facilities.
+			These facilities are represented as compiler
+			options, defined in arc_options.def file.
+
+   DEF_HW_FACILITIES	Default flags for this architecture.  It is a
+			subset of DEV_HW_FACILITIES.  */
+
+ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
+	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
+	  | FL_SIMD | FL_FPUDA, 0)
+ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
+	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
+	  | FL_FPUS | FL_FPUD,						\
+	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
+ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
+	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
+ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
+	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
+	  FL_BS | FL_NORM | FL_SWAP)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
index 065e973..4cfd7b6 100644
--- a/gcc/config/arc/arc-c.def
+++ b/gcc/config/arc/arc-c.def
@@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__",     TARGET_EM)
 ARC_C_DEF ("__HS__",     TARGET_HS)
 ARC_C_DEF ("__Xnorm",    TARGET_NORM)
 ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
new file mode 100644
index 0000000..0ceb734
--- /dev/null
+++ b/gcc/config/arc/arc-cpus.def
@@ -0,0 +1,75 @@
+/* ARC CPU architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of various ARC CPU configurations.  If updated, cd to
+   $(builddir)/gcc and run
+
+   $ make arc-cpus
+
+   This will regenerate / update the following source files:
+
+   -  $(srcdir)/config/arc/t-multilib
+   -  $(srcdir)/config/arc/arc-tables.opt
+
+   After that, rebuild everything and check-in the new sources to the
+   repo.  This file defines the accepted values for -mcpu=<CPU>
+   option.
+
+   Before including this file, define a macro:
+
+   ARC_CPU (NAME, ARCH, FLAGS, TUNE)
+
+   where the arguments are the fields of arc_cpu_t:
+
+   NAME	  A given arbitrary name.
+   ARCH	  Base architecture for the given CPU.
+   FLAGS  Specific hardware flags that are enabled by this CPU configuration,
+	  as defined in arc-options.def file, and allowed by arc-arches.def
+	  file.  The specific hardware flags are enumerated without using
+	  spaces between the '|' character and consequtive flags.
+   TUNE	  Tune value for the given configuration, otherwise NONE.  */
+
+ARC_CPU (em,	    em, 0, NONE)
+ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
+ARC_CPU (em4,	    em, FL_CD, NONE)
+ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
+ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
+ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
+
+ARC_CPU (hs,	     hs, 0, NONE)
+ARC_CPU (archs,	     hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs34,	     hs, FL_MPYOPT_2, NONE)
+ARC_CPU (hs38,	     hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE)
+
+ARC_CPU (arc600,	  6xx, FL_BS, ARC600)
+ARC_CPU (arc600_norm,	  6xx, FL_BS|FL_NORM, ARC600)
+ARC_CPU (arc600_mul64,	  6xx, FL_BS|FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600)
+ARC_CPU (arc601,	  6xx, 0, ARC600)
+ARC_CPU (arc601_norm,	  6xx, FL_NORM, ARC600)
+ARC_CPU (arc601_mul64,	  6xx, FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600)
+
+ARC_CPU (arc700, 700, 0, ARC700_4_2_STD)
+ARC_CPU (nps400, 700, 0, ARC700_4_2_STD)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
new file mode 100644
index 0000000..0f9d36c
--- /dev/null
+++ b/gcc/config/arc/arc-options.def
@@ -0,0 +1,109 @@
+/* ARC options.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of all known ARC hardware modifier options (i.e., compiler
+   options that are selecting a hardware facility).  There can be two
+   types options: simple switches (e.g. code-density option can be
+   on/off), or can accept multiple values (e.g., fpu options).
+
+   For any valid HW option, define a macro:
+
+   ARC_OPT (NAME, CODE, MASK, DOC)
+
+   where:
+   NAME	  Name (identifier) of a particular hardware modifier option,
+	  as in enum cpu_flags.
+
+   CODE	  64-bit mask used to encode NAME.
+
+   MASK	  Corresponding GCC's MASK_<option> macro.
+
+   DOC	  A string used when emitting compiler errors or warnings.
+
+   For a multi-value option, define a macro for a valid value:
+
+   ARC_OPTX (NAME, CODE, VAR, VAL, DOC)
+
+   where:
+   NAME	  Name (identifier) of a particular hardware modifier
+	  configuration.
+
+   CODE	  64-bit mask used to encode NAME.  It will be encoded in the
+	  same variable like options given via ARC_OPT.
+
+   VAR	  Corresponding GCC's option variable.
+
+   VAL	  Value to be set in VAR.
+
+   DOC	  A string used when emitting compiler errors or warnings.
+
+   All multi-value options are defined using ARC_OPTX and ARC_OPT.
+   ARC_OPT contains a mask with all valid values for the given
+   option.  */
+
+ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
+ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
+ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
+
+ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
+ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
+ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
+ARC_OPT (FL_SWAP,     (1ULL << 7), MASK_SWAP_SET,	   "swap")
+ARC_OPT (FL_MUL64,    (1ULL << 8), MASK_MUL64_SET,	   "mul64")
+ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16")
+
+ARC_OPT (FL_EA,	      (1ULL << 11), MASK_EA_SET,	   "extended arithmetics")
+ARC_OPT (FL_SPFP,     (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX")
+ARC_OPT (FL_DPFP,     (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX")
+ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET,	   "argonaut")
+ARC_OPT (FL_SIMD,     (1ULL << 15), MASK_SIMD_SET,	   "simd")
+
+ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w")
+ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1")
+ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2")
+ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3")
+ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4")
+ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5")
+ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy")
+ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd")
+ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw")
+
+ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option")
+ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option")
+
+ARC_OPTX (FL_FPU_FPUS,	    (1ULL << 26), arc_fpu_build, FPU_FPUS,	"mfpu=fpus")
+ARC_OPTX (FL_FPU_FPUS_DIV,  (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV,	"mfpu=fpus_div")
+ARC_OPTX (FL_FPU_FPUS_FMA,  (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA,	"mfpu=fpus_fma")
+ARC_OPTX (FL_FPU_FPUS_ALL,  (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL,	"mfpu=fpus_all")
+ARC_OPTX (FL_FPU_FPUDA,	    (1ULL << 30), arc_fpu_build, FPU_FPUDA,	"mfpu=fpuda")
+ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div")
+ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma")
+ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all")
+ARC_OPTX (FL_FPU_FPUD,	    (1ULL << 34), arc_fpu_build, FPU_FPUD,	"mfpu=fpud")
+ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV,	"mfpu=fpud_div")
+ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA,	"mfpu=fpud_fma")
+ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL,	"mfpu=fpud_all")
+
+ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
+ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
+ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
index cbd7898..81446b4 100644
--- a/gcc/config/arc/arc-opts.h
+++ b/gcc/config/arc/arc-opts.h
@@ -18,15 +18,16 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef ARC_OPTS_H
+#define ARC_OPTS_H
+
 enum processor_type
 {
-  PROCESSOR_NONE,
-  PROCESSOR_ARC600,
-  PROCESSOR_ARC601,
-  PROCESSOR_ARC700,
-  PROCESSOR_NPS400,
-  PROCESSOR_ARCEM,
-  PROCESSOR_ARCHS
+  PROCESSOR_NONE = 0,
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)  PROCESSOR_##NAME,
+#include "arc-cpus.def"
+#undef ARC_CPU
+  PROCESSOR_generic
 };
 
 /* Single precision floating point.  */
@@ -48,3 +49,35 @@ enum processor_type
 /* Double precision floating point assist operations.  */
 #define FPX_DP    0x0100
 
+/* fpus option combi.  */
+#define FPU_FPUS  (FPU_SP | FPU_SC)
+/* fpud option combi.  */
+#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+/* fpuda option combi.  */
+#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
+/* fpuda_div option combi.  */
+#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+/* fpuda_fma option combi.  */
+#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+/* fpuda_all option combi.  */
+#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+/* fpus_div option combi.  */
+#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
+/* fpus_fma option combi.  */
+#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
+/* fpus_all option combi.  */
+#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+/* fpud_div option combi.  */
+#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
+/* fpud_fma option combi.  */
+#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
+/* fpud_all option combi.  */
+#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+
+/* Default FPU option value.  */
+#define DEFAULT_arc_fpu_build 0x10000000
+
+/* Default MPY option value.  */
+#define DEFAULT_arc_mpy_option -1
+
+#endif /* ARC_OPTS_H */
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index ad5d4d3..d1266b4 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
 #endif /* TREE_CODE */
 
 
-extern void arc_init (void);
 extern unsigned int arc_compute_frame_size (int);
 extern bool arc_ccfsm_branch_deleted_p (void);
 extern void arc_ccfsm_record_branch_deleted (void);
diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
new file mode 100644
index 0000000..0e7c50c
--- /dev/null
+++ b/gcc/config/arc/arc-tables.opt
@@ -0,0 +1,90 @@
+; Auto-generated Makefile Snip
+; Generated by    : ./gcc/config/arc/genoptions.awk
+; Generated from  : ./gcc/config/arc/arc-cpu.def
+;
+; Copyright (C) 2016 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+Enum
+Name(processor_type) Type(enum processor_type)
+Known ARC CPUs (for use with the -mcpu= option):
+
+EnumValue
+Enum(processor_type) String(em) Value(PROCESSOR_em)
+
+EnumValue
+Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
+
+EnumValue
+Enum(processor_type) String(em4) Value(PROCESSOR_em4)
+
+EnumValue
+Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips)
+
+EnumValue
+Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
+
+EnumValue
+Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
+
+EnumValue
+Enum(processor_type) String(hs) Value(PROCESSOR_hs)
+
+EnumValue
+Enum(processor_type) String(archs) Value(PROCESSOR_archs)
+
+EnumValue
+Enum(processor_type) String(hs34) Value(PROCESSOR_hs34)
+
+EnumValue
+Enum(processor_type) String(hs38) Value(PROCESSOR_hs38)
+
+EnumValue
+Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux)
+
+EnumValue
+Enum(processor_type) String(arc600) Value(PROCESSOR_arc600)
+
+EnumValue
+Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm)
+
+EnumValue
+Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64)
+
+EnumValue
+Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc601) Value(PROCESSOR_arc601)
+
+EnumValue
+Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm)
+
+EnumValue
+Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64)
+
+EnumValue
+Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc700) Value(PROCESSOR_arc700)
+
+EnumValue
+Enum(processor_type) String(nps400) Value(PROCESSOR_nps400)
+
+
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 5e8d6b4..8810e91 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -64,7 +64,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 
 /* Which cpu we're compiling for (ARC600, ARC601, ARC700).  */
-static const char *arc_cpu_string = "";
+static char arc_cpu_name[10] = "";
+static const char *arc_cpu_string = arc_cpu_name;
 
 /* ??? Loads can handle any constant, stores can only handle small ones.  */
 /* OTOH, LIMMs cost extra, so their usefulness is limited.  */
@@ -241,6 +242,12 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
 						enum by_pieces_operation op,
 						bool);
 
+static const arc_cpu_t *arc_selected_cpu;
+static const arc_arch_t *arc_selected_arch;
+
+/* Global var which sets the current compilation architecture.  */
+enum base_architecture arc_base_cpu;
+
 /* Implements target hook vector_mode_supported_p.  */
 
 static bool
@@ -668,47 +675,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
 
 /* Called by OVERRIDE_OPTIONS to initialize various things.  */
 
-void
+static void
 arc_init (void)
 {
-  enum attr_tune tune_dflt = TUNE_NONE;
-
-  switch (arc_cpu)
-    {
-    case PROCESSOR_ARC600:
-      arc_cpu_string = "ARC600";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC601:
-      arc_cpu_string = "ARC601";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC700:
-      arc_cpu_string = "ARC700";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_NPS400:
-      arc_cpu_string = "NPS400";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_ARCEM:
-      arc_cpu_string = "EM";
-      break;
-
-    case PROCESSOR_ARCHS:
-      arc_cpu_string = "HS";
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  if (arc_tune == TUNE_NONE)
-    arc_tune = tune_dflt;
   /* Note: arc_multcost is only used in rtx_cost if speed is true.  */
   if (arc_multcost < 0)
     switch (arc_tune)
@@ -739,18 +708,10 @@ arc_init (void)
 	break;
       }
 
-  /* Support mul64 generation only for ARC600.  */
-  if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul64 not supported for ARC700 or ARCv2");
-
   /* MPY instructions valid only for ARC700 or ARCv2.  */
   if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
       error ("-mno-mpy supported only for ARC700 or ARCv2");
 
-  /* mul/mac instructions only for ARC600.  */
-  if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul32x16 supported only for ARC600 or ARC601");
-
   if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
       error ("-mno-dpfp-lrsr supported only with -mdpfp");
 
@@ -763,23 +724,11 @@ arc_init (void)
   if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
     error ("-mspfp_fast not available on ARC600 or ARC601");
 
-  /* FPX-3. No FPX extensions on pre-ARC600 cores.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
-    error ("FPX extensions not available on pre-ARC600 cores");
-
-  /* FPX-4.  No FPX extensions mixed with FPU extensions for ARC HS
-     cpus.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && TARGET_HARD_FLOAT
-      && TARGET_HS)
+  /* FPX-4.  No FPX extensions mixed with FPU extensions.  */
+  if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
+      && TARGET_HARD_FLOAT)
     error ("No FPX/FPU mixing allowed");
 
-  /* Only selected multiplier configurations are available for HS.  */
-  if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
-		    || (arc_mpy_option == 1)))
-    error ("This multiplier configuration is not available for HS cores");
-
   /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic.  */
   if (flag_pic && TARGET_ARC600_FAMILY)
     {
@@ -789,26 +738,6 @@ arc_init (void)
       flag_pic = 0;
     }
 
-  if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS))
-    error ("-matomic is only supported for ARC700 or ARC HS cores");
-
-  /* ll64 ops only available for HS.  */
-  if (TARGET_LL64 && !TARGET_HS)
-    error ("-mll64 is only supported for ARC HS cores");
-
-  /* FPU support only for V2.  */
-  if (TARGET_HARD_FLOAT)
-    {
-      if (TARGET_EM
-	  && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
-	error ("FPU double precision options are available for ARC HS only");
-      if (TARGET_HS && (arc_fpu_build & FPX_DP))
-	error ("FPU double precision assist "
-	       "options are not available for ARC HS");
-      if (!TARGET_HS && !TARGET_EM)
-	error ("FPU options are available for ARCv2 architecture only");
-    }
-
   arc_init_reg_tables ();
 
   /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
@@ -853,7 +782,86 @@ static void
 arc_override_options (void)
 {
   if (arc_cpu == PROCESSOR_NONE)
-    arc_cpu = PROCESSOR_ARC700;
+    arc_cpu = TARGET_CPU_DEFAULT;
+
+  /* Set the default cpu options.  */
+  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
+  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
+  arc_base_cpu = arc_selected_arch->arch;
+
+  /* Set the architectures.  */
+  switch (arc_selected_arch->arch)
+    {
+    case BASE_ARCH_em:
+      arc_cpu_string = "EM";
+      break;
+    case BASE_ARCH_hs:
+      arc_cpu_string = "HS";
+      break;
+    case BASE_ARCH_700:
+      arc_cpu_string = "ARC700";
+      break;
+    case BASE_ARCH_6xx:
+      arc_cpu_string = "ARC600";
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
+     specific flags are set in arc-common.c.  The architecture forces
+     the default hardware configurations in, regardless what command
+     line options are saying.  The CPU optional hw options can be
+     turned on or off.  */
+#define ARC_OPT(NAME, CODE, MASK, DOC)			\
+  do {							\
+    if ((arc_selected_cpu->flags & CODE)		\
+	&& ((target_flags_explicit & MASK) == 0))	\
+      target_flags |= MASK;				\
+    if (arc_selected_arch->dflags & CODE)		\
+      target_flags |= MASK;				\
+  } while (0);
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
+  do {						\
+    if ((arc_selected_cpu->flags & CODE)	\
+	&& (VAR == DEFAULT_##VAR))		\
+      VAR = VAL;				\
+    if (arc_selected_arch->dflags & CODE)	\
+      VAR = VAL;				\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Check options against architecture options.  Throw an error if
+     option is not allowed.  */
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
+  do {								\
+    if ((VAR == VAL)						\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      {								\
+	error ("%s is not available for %s architecture",	\
+	       DOC, arc_selected_arch->name);			\
+      }								\
+  } while (0);
+#define ARC_OPT(NAME, CODE, MASK, DOC)				\
+  do {								\
+    if ((target_flags & MASK)					\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      error ("%s is not available for %s architecture",		\
+	     DOC, arc_selected_arch->name);			\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Set Tune option.  */
+  if (arc_tune == TUNE_NONE)
+    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
 
   if (arc_size_opt_level == 3)
     optimize_size = 1;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index c02e1cd..0f97afc 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ARC_H
 #define GCC_ARC_H
 
+#include <stdbool.h>
+
 /* Things to do:
 
    - incscc, decscc?
@@ -39,6 +41,10 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
 #define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
 
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT	PROCESSOR_arc700
+#endif
+
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)	\
 	((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
@@ -74,9 +80,11 @@ along with GCC; see the file COPYING3.  If not see
       GNU_USER_TARGET_OS_CPP_BUILTINS (); \
     } \
   while (0)
-#endif
 
-/* Match the macros used in the assembler.  */
+#endif /* DEFAULT_LIBC == LIBC_UCLIBC */
+
+/* Macros enabled by specific command line option.  FIXME: to be
+   deprecatd.  */
 #define CPP_SPEC "\
 %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \
 %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \
@@ -85,34 +93,22 @@ along with GCC; see the file COPYING3.  If not see
 %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \
 %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \
 %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \
-%{mcpu=NPS400:-D__NPS400__} \
-%{mcpu=nps400:-D__NPS400__} \
-"
+%{mcpu=nps400:-D__NPS400__}"
 
 #define CC1_SPEC "\
 %{EB:%{EL:%emay not use both -EB and -EL}} \
 %{EB:-mbig-endian} %{EL:-mlittle-endian} \
 "
+extern const char *arc_cpu_to_as (int argc, const char **argv);
+
+#define EXTRA_SPEC_FUNCTIONS			\
+  { "cpu_to_as", arc_cpu_to_as },
+
+#define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "			\
+  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
 
-#define ASM_DEFAULT "-mARC700 -mEA"
-
-#define ASM_SPEC  "\
-%{mbig-endian|EB:-EB} %{EL} \
-%{mcpu=ARC600:-mARC600} \
-%{mcpu=ARC601:-mARC601} \
-%{mcpu=ARC700:-mARC700} \
-%{mcpu=ARC700:-mEA} \
-%{!mcpu=*:" ASM_DEFAULT "} \
-%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \
-%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \
-%{msimd} \
-%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \
-%{mcpu=ARC700|!mcpu=*:%{mlock}} \
-%{mcpu=ARC700|!mcpu=*:%{mswape}} \
-%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \
-%{mcpu=ARCHS:-mHS} \
-%{mcpu=ARCEM:-mEM} \
-%{matomic:-mlock}"
+#define OPTION_DEFAULT_SPECS						\
+  {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
 
 #if DEFAULT_LIBC == LIBC_UCLIBC
 /* Note that the default is to link against dynamic libraries, if they are
@@ -196,17 +192,11 @@ along with GCC; see the file COPYING3.  If not see
 #define TARGET_MMEDIUM_CALLS_DEFAULT 0
 #endif
 
-#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \
-  "%{mARC600|mA6: -mcpu=ARC600 %<mARC600 %<mA6}" \
-  "%{mARC601: -mcpu=ARC601 %<mARC601}" \
-  "%{mARC700|mA7: -mcpu=ARC700 %<mARC700 %<mA7}" \
-  "%{mbarrel_shifte*: -mbarrel-shifte%* %<mbarrel_shifte*}" \
-  "%{mEA: -mea %<mEA}" \
-  "%{mspfp_*: -mspfp-%* %<mspfp_*}" \
-  "%{mdpfp_*: -mdpfp-%* %<mdpfp_*}" \
-  "%{mdsp_pack*: -mdsp-pack%* %<mdsp_pack*}" \
-  "%{mmac_*: -mmac-%* %<mmac_*}" \
-  "%{multcost=*: -mmultcost=%* %<multcost=*}"
+#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS		   \
+  "%{mARC600|mA6: -mcpu=arc600 %<mARC600 %<mA6 %<mARC600}"	   \
+  "%{mARC601: -mcpu=arc601 %<mARC601}"				   \
+  "%{mARC700|mA7: -mcpu=arc700 %<mARC700 %<mA7}"		   \
+  "%{mEA: -mea %<mEA}"
 
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
@@ -252,20 +242,21 @@ along with GCC; see the file COPYING3.  If not see
    use conditional execution?  */
 #define TARGET_AT_DBR_CONDEXEC  (!TARGET_ARC700 && !TARGET_V2)
 
-#define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
-#define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
-#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700	\
-		       || arc_cpu == PROCESSOR_NPS400)
-#define TARGET_EM     (arc_cpu == PROCESSOR_ARCEM)
-#define TARGET_HS     (arc_cpu == PROCESSOR_ARCHS)
-#define TARGET_V2							\
-  ((arc_cpu == PROCESSOR_ARCHS) || (arc_cpu == PROCESSOR_ARCEM))
-
-/* Recast the cpu class to be the cpu attribute.  */
-#define arc_cpu_attr ((enum attr_cpu)arc_cpu)
-
-#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mARC700" }
+extern enum base_architecture arc_base_cpu;
+
+#define TARGET_ARC600 ((arc_base_cpu == BASE_ARCH_6xx)	\
+		       && (TARGET_BARREL_SHIFTER))
+#define TARGET_ARC601 ((arc_base_cpu == BASE_ARCH_6xx)	\
+		       && (!TARGET_BARREL_SHIFTER))
+#define TARGET_ARC700 (arc_base_cpu == BASE_ARCH_700)
+#define TARGET_EM (arc_base_cpu == BASE_ARCH_em)
+#define TARGET_HS (arc_base_cpu == BASE_ARCH_hs)
+#define TARGET_V2 (TARGET_EM || TARGET_HS)
+
+#ifdef ARC_MULTILIB_CPU_DEFAULT
+# ifndef MULTILIB_DEFAULTS
+#  define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT }
+# endif
 #endif
 
 #ifndef UNALIGNED_ACCESS_DEFAULT
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 715da31..6f757b6 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -231,11 +231,6 @@
 	 (eq_attr "is_CALL" "yes") (const_string "yes")]
 	(const_string "no")))
 
-
-;; Attribute describing the processor
-(define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
-  (const (symbol_ref "arc_cpu_attr")))
-
 ;; true for compact instructions (those with _s suffix)
 ;; "maybe" means compact unless we conditionalize the insn.
 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 4caf366..20a526b 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -53,9 +53,12 @@ mARC700
 Target Report
 Same as -mA7.
 
+TargetVariable
+int arc_mpy_option = DEFAULT_arc_mpy_option
+
 mmpy-option=
-Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
--mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
+Target RejectNegative Joined
+-mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
 
 mdiv-rem
 Target Report Mask(DIVREM)
@@ -100,7 +103,7 @@ Target Report Mask(MUL64_SET)
 Generate mul64 and mulu64 instructions.
 
 mno-mpy
-Target Report Mask(NOMPY_SET)
+Target Report Mask(NOMPY_SET) Warn(%qs is deprecated)
 Do not generate mpy instructions for ARC700.
 
 mea
@@ -167,45 +170,6 @@ mcpu=
 Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
 -mcpu=CPU	Compile code for ARC variant CPU.
 
-Enum
-Name(processor_type) Type(enum processor_type)
-
-EnumValue
-Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(arc600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(arc601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(arcem) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(ARCHS) Value(PROCESSOR_ARCHS)
-
-EnumValue
-Enum(processor_type) String(archs) Value(PROCESSOR_ARCHS)
-
 msize-level=
 Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
 size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os.
@@ -308,25 +272,25 @@ Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
 ; Flags used by the assembler, but for which we define preprocessor
 ; macro symbols as well.
 mcrc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable variable polynomial CRC extension.
 
 mdsp-packa
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable DSP 3.1 Pack A extensions.
 
 mdvbf
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable dual viterbi butterfly extension.
 
 mmac-d16
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mmac-24
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mtelephony
-Target Report RejectNegative
+Target Report RejectNegative Warn(%qs is deprecated)
 Enable Dual and Single Operand Instructions for Telephony.
 
 mxy
@@ -343,7 +307,7 @@ Target Report
 Enable swap byte ordering extension instruction.
 
 mrtsc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable 64-bit Time-Stamp Counter extension instruction.
 
 EB
@@ -394,24 +358,6 @@ Target
 multcost=
 Target RejectNegative Joined
 
-; Unfortunately, listing the full option name gives us clashes
-; with OPT_opt_name being claimed for both opt_name and opt-name,
-; so we leave out the last character or more.
-mbarrel_shifte
-Target Joined
-
-mspfp_
-Target Joined
-
-mdpfp_
-Target Joined
-
-mdsp_pack
-Target Joined
-
-mmac_
-Target Joined
-
 matomic
 Target Report Mask(ATOMIC)
 Enable atomic instructions.
@@ -421,47 +367,47 @@ Target Report Mask(LL64)
 Enable double load/store instructions for ARC HS.
 
 mfpu=
-Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
+Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(DEFAULT_arc_fpu_build)
 Specify the name of the target floating point configuration.
 
 Enum
 Name(arc_fpu) Type(int)
 
 EnumValue
-Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
+Enum(arc_fpu) String(fpus) Value(FPU_FPUS)
 
 EnumValue
-Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+Enum(arc_fpu) String(fpud) Value(FPU_FPUD)
 
 EnumValue
-Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
+Enum(arc_fpu) String(fpuda) Value(FPU_FPUDA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_div) Value(FPU_FPUDA_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+Enum(arc_fpu) String(fpuda_fma) Value(FPU_FPUDA_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_all) Value(FPU_FPUDA_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
+Enum(arc_fpu) String(fpus_div) Value(FPU_FPUS_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
+Enum(arc_fpu) String(fpud_div) Value(FPU_FPUD_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
+Enum(arc_fpu) String(fpus_fma) Value(FPU_FPUS_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
+Enum(arc_fpu) String(fpud_fma) Value(FPU_FPUD_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+Enum(arc_fpu) String(fpus_all) Value(FPU_FPUS_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL)
 
 mtp-regno=
 Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25)
diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
new file mode 100644
index 0000000..6117968
--- /dev/null
+++ b/gcc/config/arc/driver-arc.c
@@ -0,0 +1,78 @@
+/* Subroutines for the gcc driver.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu <claziss@synopsys.com>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+/* Returns command line parameters to pass to as.  */
+
+const char*
+arc_cpu_to_as (int argc, const char **argv)
+{
+  const char *name = NULL;
+  const arc_cpu_t *arc_selected_cpu;
+
+  /* No argument, check what is the default cpu.  */
+  if (argc == 0)
+    {
+      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
+    }
+  else
+    {
+      name = argv[0];
+      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
+	   arc_selected_cpu++)
+	{
+	  if (strcmp (arc_selected_cpu->name, name) == 0)
+	    break;
+	}
+    }
+
+  switch (arc_selected_cpu->arch)
+    {
+    case BASE_ARCH_em:
+      if (arc_selected_cpu->flags & FL_CD)
+	name = "-mcode-density";
+      else
+	name = "";
+      if (arc_selected_cpu->flags & FL_FPUDA)
+	name = concat ("-mfpuda ", name, NULL);
+      if (arc_selected_cpu->flags & FL_SPFP)
+	name = concat ("-mspfp ", name, NULL);
+      if (arc_selected_cpu->flags & FL_DPFP)
+	name = concat ("-mdpfp ", name, NULL);
+      return concat ("-mcpu=arcem ", name, NULL);
+    case BASE_ARCH_hs:
+      return "-mcpu=archs";
+    case BASE_ARCH_700:
+      return "-mcpu=arc700 -mEA";
+    case BASE_ARCH_6xx:
+      if (arc_selected_cpu->flags & FL_MUL64)
+	return "-mcpu=arc600 -mmul64 -mnorm";
+      if (arc_selected_cpu->flags & FL_MUL32x16)
+	return "-mcpu=arc600 -mdsp-packa -mnorm";
+      return "-mcpu=arc600 -mnorm";
+    default:
+      gcc_unreachable ();
+    }
+  return NULL;
+}
diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
new file mode 100644
index 0000000..5934f4f
--- /dev/null
+++ b/gcc/config/arc/genmultilib.awk
@@ -0,0 +1,203 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+# Transform CPU Information from arc-cpu.def to a
+# Representation that is understood by GCC's multilib Machinery.
+#
+# The Script works as a Filter from STDIN to STDOUT.
+#
+# FORMAT = "Makefile": Generate Makefile Snipet that sets some
+#                      MULTILIB_* Variables as needed.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+  n_reuse = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "# Auto-generated Makefile Snip"
+	  print "# Generated by    : ./gcc/config/arc/genmultilib.awk"
+	  print "# Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print "# Used by         : tmake_file from Makefile and genmultilib"
+	  print ""
+	}
+    }
+
+  comment = 2;
+
+  print
+}
+
+/^$/ {
+  # The first empty line stops copy-pasting the GPL comments
+  # from this file to the generated file.
+
+  comment = 0
+}
+
+
+/^ARC_CPU/ {
+  name = $2
+  #  gsub ("\"", "", name)
+
+  if ($4 != "0")
+    {
+      arch = $3
+      if (arch == "6xx")
+	arch = 601
+
+      n = split ($4, cpu_flg, "|")
+
+      line = "mcpu." arch
+      for (i = 1; i <= n; i++)
+	{
+	  if (cpu_flg[i] == "FL_MPYOPT_0")
+	    line = line "/mmpy-option.0"
+	  else if (cpu_flg[i] == "FL_MPYOPT_1")
+	    line = line "/mmpy-option.1"
+	  else if (cpu_flg[i] == "FL_MPYOPT_2")
+	    line = line "/mmpy-option.2"
+	  else if (cpu_flg[i] == "FL_MPYOPT_3")
+	    line = line "/mmpy-option.3"
+	  else if (cpu_flg[i] == "FL_MPYOPT_4")
+	    line = line "/mmpy-option.4"
+	  else if (cpu_flg[i] == "FL_MPYOPT_5")
+	    line = line "/mmpy-option.5"
+	  else if (cpu_flg[i] == "FL_MPYOPT_6")
+	    line = line "/mmpy-option.6"
+	  else if (cpu_flg[i] == "FL_MPYOPT_7")
+	    line = line "/mmpy-option.7"
+	  else if (cpu_flg[i] == "FL_MPYOPT_8")
+	    line = line "/mmpy-option.8"
+	  else if (cpu_flg[i] == "FL_MPYOPT_9")
+	    line = line "/mmpy-option.9"
+	  else if (cpu_flg[i] == "FL_CD")
+	    line = line "/mcode-density"
+	  else if (cpu_flg[i] == "FL_BS")
+	    line = line "/mbarrel-shifter"
+	  else if (cpu_flg[i] == "FL_DIVREM")
+	    line = line "/mdiv-rem"
+	  else if (cpu_flg[i] == "FL_NORM" \
+		   || cpu_flg[i] == "FL_SWAP")
+	    line = line "/mnorm"
+	  else if (cpu_flg[i] == "FL_FPU_FPUS")
+	    line = line "/mfpu.fpus"
+	  else if (cpu_flg[i] == "FL_FPU_FPUDA")
+	    line = line "/mfpu.fpuda"
+	  else if (cpu_flg[i] == "FL_FPU_FPUD_ALL")
+	    line = line "/mfpu.fpud_all"
+	  else if (cpu_flg[i] == "FL_LL64")
+	    line = line "/mll64"
+	  else if (cpu_flg[i] == "FL_MUL64")
+	    line = line "/mmul64"
+	  else if (cpu_flg[i] == "FL_MUL32x16")
+	    line = line "/mmul32x16"
+	  else if (cpu_flg[i] == "FL_FPX_QUARK")
+	    line = line "/quark"
+	  else if (cpu_flg[i] == "FL_SPFP")
+	    line = line "/spfp"
+	  else if (cpu_flg[i] == "FL_DPFP")
+	    line = line "/dpfp"
+	  else
+	    {
+	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
+	      exit 1
+	    }
+	}
+      line = "mcpu." name "=" line
+      reuse[n_reuse] = line
+      n_reuse++
+    }
+
+  core = name
+  cores[n_cores] = core
+  n_cores++
+}
+
+##################################################################
+#
+# We gathered all the Information, now build/output the following:
+#
+#    awk Variable         target Variable          FORMAT
+#  -----------------------------------------------------------
+#    m_options     <->    MULTILIB_OPTIONS         Makefile
+#    m_dirnames    <->    MULTILIB_DIRNAMES           "
+#
+##################################################################
+
+END {
+  m_options    = "\nMULTILIB_OPTIONS = "
+  m_dirnames   = "\nMULTILIB_DIRNAMES ="
+  m_reuse      = "\nMULTILIB_REUSE ="
+
+  sep = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options  = m_options sep "mcpu=" cores[c]
+      m_dirnames = m_dirnames " " cores[c]
+      sep = "/"
+    }
+
+  sep = ""
+  for (c = 0; c < n_reuse; c++)
+    {
+      m_reuse = m_reuse sep reuse[c]
+      sep = "\nMULTILIB_REUSE +="
+    }
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+      # Intended Target: ./gcc/config/arc/t-multilib
+
+      print m_options
+      print m_dirnames
+
+      ############################################################
+      # Legacy Aliases
+      ############################################################
+
+      print ""
+      print "# Aliases:"
+      print "MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mA6"
+      print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601"
+      print "MULTILIB_MATCHES += mcpu?arc700=mA7"
+      print "MULTILIB_MATCHES += mcpu?arc700=mARC700"
+    }
+}
diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk
new file mode 100644
index 0000000..24a93eb
--- /dev/null
+++ b/gcc/config/arc/genoptions.awk
@@ -0,0 +1,86 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "; Auto-generated Makefile Snip"
+	  print "; Generated by    : ./gcc/config/arc/genoptions.awk"
+	  print "; Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print ";"
+	}
+    }
+
+  comment = 2;
+
+  gsub ("^#", ";", $0)
+  print
+}
+
+/^$/ {
+    # The first empty line stops copy-pasting the GPL comments
+    # from this file to the generated file.
+    comment = 0
+}
+
+/^ARC_CPU/ {
+  name = $2
+  cores[n_cores] = name;
+  n_cores++
+}
+
+END {
+  m_option = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options = m_options "EnumValue\nEnum(processor_type) String(" \
+	cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n"
+    }
+
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+	print "\nEnum"
+	print "Name(processor_type) Type(enum processor_type)"
+	print "Known ARC CPUs (for use with the -mcpu= option):\n"
+	print m_options
+    }
+}
diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
index 4252e73..bdb1328 100644
--- a/gcc/config/arc/t-arc
+++ b/gcc/config/arc/t-arc
@@ -19,11 +19,30 @@
 
 TM_H += $(srcdir)/config/arc/arc-c.def
 
+driver-arc.o: $(srcdir)/config/arc/driver-arc.c \
+  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
 arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \
 $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arc/arc-c.c
 
+#Run `arc-cpus` if you changed something in arc-cpus.def
+
+.PHONY: arc-cpus
+
+arc-cpus: $(srcdir)/config/arc/t-multilib \
+	$(srcdir)/config/arc/arc-tables.opt
+
+$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk 	\
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
+$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
 # Local Variables:
 # mode: Makefile
 # End:
diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib
deleted file mode 100644
index c49a3fcc..0000000
--- a/gcc/config/arc/t-arc-newlib
+++ /dev/null
@@ -1,46 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm
-MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm
-#
-# Aliases:
-MULTILIB_MATCHES  = mcpu?ARC600=mcpu?arc600
-MULTILIB_MATCHES += mcpu?ARC600=mARC600
-MULTILIB_MATCHES += mcpu?ARC600=mA6
-MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
-MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
-MULTILIB_MATCHES += mcpu?ARC700=mA7
-MULTILIB_MATCHES += mcpu?ARC700=mARC700
-MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700
-MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem
-MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs
-MULTILIB_MATCHES += EL=mlittle-endian
-MULTILIB_MATCHES += EB=mbig-endian
-#
-# These don't make sense for the ARC700 default target:
-MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm*
-# And neither of the -mmul* options make sense without -mnorm:
-MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
-# Exclusions for ARC700
-MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16*
-# Exclusions for ARCv2EM
-MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16*
-# Exclusions for ARCv2HS
-MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm*
diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-arc-uClibc
deleted file mode 100644
index 11e81f1..0000000
--- a/gcc/config/arc/t-arc-uClibc
+++ /dev/null
@@ -1,20 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
new file mode 100644
index 0000000..5a36af6
--- /dev/null
+++ b/gcc/config/arc/t-multilib
@@ -0,0 +1,34 @@
+# Auto-generated Makefile Snip
+# Generated by    : ./gcc/config/arc/genmultilib.awk
+# Generated from  : ./gcc/config/arc/arc-cpu.def
+# Used by         : tmake_file from Makefile and genmultilib
+
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
+
+MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
+
+# Aliases:
+MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
+MULTILIB_MATCHES += mcpu?arc600=mARC600
+MULTILIB_MATCHES += mcpu?arc600=mA6
+MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601
+MULTILIB_MATCHES += mcpu?arc700=mA7
+MULTILIB_MATCHES += mcpu?arc700=mARC700
diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc
new file mode 100644
index 0000000..11e81f1
--- /dev/null
+++ b/gcc/config/arc/t-uClibc
@@ -0,0 +1,20 @@
+# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
+
+# Copyright (C) 2007-2016 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+
+# You should have received a copy of the GNU General Public License along
+# with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3f9c0a0..4399733 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13882,29 +13882,92 @@ values for @var{cpu} are
 @table @samp
 @opindex mA6
 @opindex mARC600
-@item ARC600
 @item arc600
 Compile for ARC600.  Aliases: @option{-mA6}, @option{-mARC600}.
 
-@item ARC601
 @item arc601
 @opindex mARC601
 Compile for ARC601.  Alias: @option{-mARC601}.
 
-@item ARC700
 @item arc700
 @opindex mA7
 @opindex mARC700
 Compile for ARC700.  Aliases: @option{-mA7}, @option{-mARC700}.
 This is the default when configured with @option{--with-cpu=arc700}@.
 
-@item ARCEM
 @item arcem
 Compile for ARC EM.
 
-@item ARCHS
 @item archs
 Compile for ARC HS.
+
+@item em
+@opindex em
+Compile for ARC EM cpu with no hardware extension.
+
+@item em4
+@opindex em4
+Compile for ARC EM4 cpu.
+
+@item em4_dmips
+@opindex em4_dmips
+Compile for ARC EM4 DMIPS cpu.
+
+@item em4_fpus
+@opindex em4_fpus
+Compile for ARC EM4 DMIPS cpu with single precision floating point
+extension.
+
+@item em4_fpuda
+@opindex em4_fpuda
+Compile for ARC EM4 DMIPS cpu with single precision floating point and
+double assists instructions.
+
+@item hs
+@opindex hs
+Compile for ARC HS cpu with no hardware extension, except the atomic
+instructions.
+
+@item hs34
+@opindex hs34
+Compile for ARC HS34 cpu.
+
+@item hs38
+@opindex hs38
+Compile for ARC HS38 cpu.
+
+@item hs38_linux
+@opindex hs38_linux
+Compile for ARC HS38 cpu with all hardware extensions on.
+
+@item arc600_norm
+@opindex arc600_norm
+Compile for ARC 600 cpu with norm instruction enabled.
+
+@item arc600_mul32x16
+@opindex arc600_mul32x16
+Compile for ARC 600 cpu with norm and mul32x16 instructions enabled.
+
+@item arc600_mul64
+@opindex arc600_mul64
+Compile for ARC 600 cpu with norm and mul64 instructions enabled.
+
+@item arc601_norm
+@opindex arc601_norm
+Compile for ARC 601 cpu with norm instruction enabled.
+
+@item arc601_mul32x16
+@opindex arc601_mul32x16
+Compile for ARC 601 cpu with norm and mul32x16 instructions enabled.
+
+@item arc601_mul64
+@opindex arc601_mul64
+Compile for ARC 601 cpu with norm and mul64 instructions enabled.
+
+@item nps400
+@opindex nps400
+Compile for ARC 700 on NPS400 chip.
+
 @end table
 
 @item -mdpfp
@@ -13931,7 +13994,8 @@ supported.  This is always enabled for @option{-mcpu=ARC700}.
 
 @item -mno-mpy
 @opindex mno-mpy
-Do not generate mpy instructions for ARC700.
+Do not generate mpy instructions for ARC700.  This instruction is
+deprecated.
 
 @item -mmul32x16
 @opindex mmul32x16
@@ -14138,12 +14202,14 @@ define preprocessor macro symbols.
 @item -mdsp-packa
 @opindex mdsp-packa
 Passed down to the assembler to enable the DSP Pack A extensions.
-Also sets the preprocessor symbol @code{__Xdsp_packa}.
+Also sets the preprocessor symbol @code{__Xdsp_packa}.  This option is
+deprecated.
 
 @item -mdvbf
 @opindex mdvbf
 Passed down to the assembler to enable the dual viterbi butterfly
-extension.  Also sets the preprocessor symbol @code{__Xdvbf}.
+extension.  Also sets the preprocessor symbol @code{__Xdvbf}.  This
+option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mlock
@@ -14155,19 +14221,19 @@ Conditional extension.  Also sets the preprocessor symbol
 @item -mmac-d16
 @opindex mmac-d16
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_d16}.
+@code{__Xxmac_d16}.  This option is deprecated.
 
 @item -mmac-24
 @opindex mmac-24
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_24}.
+@code{__Xxmac_24}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mrtsc
 @opindex mrtsc
 Passed down to the assembler to enable the 64-bit Time-Stamp Counter
 extension instruction.  Also sets the preprocessor symbol
-@code{__Xrtsc}.
+@code{__Xrtsc}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mswape
@@ -14180,7 +14246,7 @@ extension instruction.  Also sets the preprocessor symbol
 @opindex mtelephony
 Passed down to the assembler to enable dual and single operand
 instructions for telephony.  Also sets the preprocessor symbol
-@code{__Xtelephony}.
+@code{__Xtelephony}.  This option is deprecated.
 
 @item -mxy
 @opindex mxy
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-10-31 15:48       ` Claudiu Zissulescu
@ 2016-11-03 22:59         ` Andrew Burgess
  2016-11-04 11:40           ` Claudiu Zissulescu
  2016-11-10 11:04           ` Claudiu Zissulescu
  0 siblings, 2 replies; 18+ messages in thread
From: Andrew Burgess @ 2016-11-03 22:59 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-10-31 16:46:17 +0100]:

> Please find the updated patch.
> 
> What is new:
> - The .def files are having a comment block on how to add new lines.
> - The arc_seen_option is not used.
> - The arc_cpu* variables are not used.
> 
> Please let me know if I miss something,

Claudiu,

Thanks for the refresh on this patch, I think that it's looking really
great.  I just had a couple of issues that I think would be worth
addressing before we merge this.

In this hunk:

> diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
> index 4caf366..20a526b 100644
> --- a/gcc/config/arc/arc.opt
> +++ b/gcc/config/arc/arc.opt
> @@ -53,9 +53,12 @@ mARC700
>  Target Report
>  Same as -mA7.
>  
> +TargetVariable
> +int arc_mpy_option = DEFAULT_arc_mpy_option
> +
>  mmpy-option=
> -Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
> --mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
> +Target RejectNegative Joined
> +-mmpy-option=MPY Compile ARCv2 code with a multiplier design option.
>  
>  mdiv-rem
>  Target Report Mask(DIVREM)
> @@ -100,7 +103,7 @@ Target Report Mask(MUL64_SET)

you create the TargetVariable arc_mpy_option, however, I think it
would be neater to fold this variable into the mmpy-option as it was
before, but, changing the type to Enum.  This would allow the big
option checking switch to be removed from arc-common.c, which I think
is a win overall.

I wasn't 100% certain that the above would actually be possible, so I
put together a prototype, I've included the patch below, that applies
on top of your patch.  Hopefully you'll agree that it's a nice clean
up.

My second question was with this hunk:

> diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
> index cbd7898..81446b4 100644
> --- a/gcc/config/arc/arc-opts.h
> +++ b/gcc/config/arc/arc-opts.h
> @@ -48,3 +49,35 @@ enum processor_type
>  /* Double precision floating point assist operations.  */
>  #define FPX_DP    0x0100
>  
> +/* fpus option combi.  */
> +#define FPU_FPUS  (FPU_SP | FPU_SC)
> +/* fpud option combi.  */
> +#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
> +/* fpuda option combi.  */
> +#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
> +/* fpuda_div option combi.  */
> +#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
> +/* fpuda_fma option combi.  */
> +#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
> +/* fpuda_all option combi.  */
> +#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
> +/* fpus_div option combi.  */
> +#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
> +/* fpus_fma option combi.  */
> +#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
> +/* fpus_all option combi.  */
> +#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
> +/* fpud_div option combi.  */
> +#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
> +/* fpud_fma option combi.  */
> +#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
> +/* fpud_all option combi.  */
> +#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
> +
> +/* Default FPU option value.  */
> +#define DEFAULT_arc_fpu_build 0x10000000
> +
> +/* Default MPY option value.  */
> +#define DEFAULT_arc_mpy_option -1
> +
> +#endif /* ARC_OPTS_H */

I wonder where the vale 0x10000000 comes from, what's the significance
of it.  I could ask the same question about the magic -1 constant, but
it's rather more obvious that -1 is just a no-value-selected magic
number.  I guess my questions for 0x10000000 are why this specific
value?  What does it mean?

My final question concerns:

> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 5e8d6b4..8810e91 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -853,7 +782,86 @@ static void
>  arc_override_options (void)
>  {
>    if (arc_cpu == PROCESSOR_NONE)
> -    arc_cpu = PROCESSOR_ARC700;
> +    arc_cpu = TARGET_CPU_DEFAULT;
> +
> +  /* Set the default cpu options.  */
> +  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
> +  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
> +  arc_base_cpu = arc_selected_arch->arch;
> +
> +  /* Set the architectures.  */
> +  switch (arc_selected_arch->arch)
> +    {
> +    case BASE_ARCH_em:
> +      arc_cpu_string = "EM";
> +      break;
> +    case BASE_ARCH_hs:
> +      arc_cpu_string = "HS";
> +      break;
> +    case BASE_ARCH_700:
> +      arc_cpu_string = "ARC700";
> +      break;
> +    case BASE_ARCH_6xx:
> +      arc_cpu_string = "ARC600";
> +      break;
> +    default:
> +      gcc_unreachable ();
> +    }
> +
> +  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
> +     specific flags are set in arc-common.c.  The architecture forces
> +     the default hardware configurations in, regardless what command
> +     line options are saying.  The CPU optional hw options can be
> +     turned on or off.  */
> +#define ARC_OPT(NAME, CODE, MASK, DOC)			\
> +  do {							\
> +    if ((arc_selected_cpu->flags & CODE)		\
> +	&& ((target_flags_explicit & MASK) == 0))	\
> +      target_flags |= MASK;				\
> +    if (arc_selected_arch->dflags & CODE)		\
> +      target_flags |= MASK;				\
> +  } while (0);
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
> +  do {						\
> +    if ((arc_selected_cpu->flags & CODE)	\
> +	&& (VAR == DEFAULT_##VAR))		\
> +      VAR = VAL;				\
> +    if (arc_selected_arch->dflags & CODE)	\
> +      VAR = VAL;				\
> +  } while (0);
> +
> +#include "arc-options.def"
> +
> +#undef ARC_OPTX
> +#undef ARC_OPT
> +
> +  /* Check options against architecture options.  Throw an error if
> +     option is not allowed.  */
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
> +  do {								\
> +    if ((VAR == VAL)						\
> +	&& (!(arc_selected_arch->flags & CODE)))		\
> +      {								\
> +	error ("%s is not available for %s architecture",	\
> +	       DOC, arc_selected_arch->name);			\
> +      }								\
> +  } while (0);
> +#define ARC_OPT(NAME, CODE, MASK, DOC)				\
> +  do {								\
> +    if ((target_flags & MASK)					\
> +	&& (!(arc_selected_arch->flags & CODE)))		\
> +      error ("%s is not available for %s architecture",		\
> +	     DOC, arc_selected_arch->name);			\
> +  } while (0);
> +
> +#include "arc-options.def"
> +
> +#undef ARC_OPTX
> +#undef ARC_OPT
> +
> +  /* Set Tune option.  */
> +  if (arc_tune == TUNE_NONE)
> +    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
>  
>    if (arc_size_opt_level == 3)
>      optimize_size = 1;

and also the driver-arc.c file.  You seem to be missing support for
nps400 in here.  Specifically, if I pass -mcpu=nps400 to GCC I'd
expect the generated assembler file to include ".cpu NPS400", and the
assembler to be driven with "-mcpu=nps400".

Admittedly we're missing a GCC test for this (there's a patch below
for just such a new test).

I think the solution could be fairly easy, if we tracked the specific
processor type in arc_cpu_t structure we could specialise in
arc_override_options and in driver-arc.c, though I don't know if you'd
agree that this is the right approach... I'm not entirely sure
myself... but it might be the easiest approach to move us forward.
Anyway, I include a patch for that below too, feel free to use or not
as you see fit.

Everything else looks fine.

Thanks,
Andrew

--- Patch #1: Changes to option handling

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";
-- 
2.6.4



^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-11-03 22:59         ` Andrew Burgess
@ 2016-11-04 11:40           ` Claudiu Zissulescu
  2016-11-10 11:04           ` Claudiu Zissulescu
  1 sibling, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-11-04 11:40 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, Francois.Bedard

Andrew,

> you create the TargetVariable arc_mpy_option, however, I think it
> would be neater to fold this variable into the mmpy-option as it was
> before, but, changing the type to Enum.  This would allow the big
> option checking switch to be removed from arc-common.c, which I think
> is a win overall.
> 
> I wasn't 100% certain that the above would actually be possible, so I
> put together a prototype, I've included the patch below, that applies
> on top of your patch.  Hopefully you'll agree that it's a nice clean
> up.

Thanks for the suggestion.

> I wonder where the vale 0x10000000 comes from, what's the significance
> of it.  I could ask the same question about the magic -1 constant, but
> it's rather more obvious that -1 is just a no-value-selected magic
> number.  I guess my questions for 0x10000000 are why this specific
> value?  What does it mean?

I need a value to mark if the variable in question is changed by a command line option or not. This is required when we set the cpu's specific configuration. I'll include this comment in the description of the define for clarity.
 
> and also the driver-arc.c file.  You seem to be missing support for
> nps400 in here.  Specifically, if I pass -mcpu=nps400 to GCC I'd
> expect the generated assembler file to include ".cpu NPS400", and the
> assembler to be driven with "-mcpu=nps400".

This patch was crafted way before the new ARC binutils to be upstreamed. Hence, it needed to work with the "old" binutils which had no support for nps400 :)
 
> Admittedly we're missing a GCC test for this (there's a patch below
> for just such a new test).
>
> I think the solution could be fairly easy, if we tracked the specific
> processor type in arc_cpu_t structure we could specialise in
> arc_override_options and in driver-arc.c, though I don't know if you'd
> agree that this is the right approach... I'm not entirely sure
> myself... but it might be the easiest approach to move us forward.
> Anyway, I include a patch for that below too, feel free to use or not
> as you see fit.

I am preparing a patch to binutils which should be able to recognize all GCC's cpu variations as valid .cpu pseudo-op argument. Hence, we can just pass to the assembler the appropriate .cpu variation seamlessly. If it is ok with you, I would like to come with a new patch on this topic after I extend .cpu support in binutils.  Alternatively, I can include your suggestion now, but then I will refurbish it later on. Please let me know what do u fancy most.

Thanks,
Claudiu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-11-03 22:59         ` Andrew Burgess
  2016-11-04 11:40           ` Claudiu Zissulescu
@ 2016-11-10 11:04           ` Claudiu Zissulescu
  2016-11-14 10:33             ` Andrew Burgess
  1 sibling, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-11-10 11:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu, Francois.Bedard, andrew.burgess

Hi,

Please find the revised patch which includes the refurbishing of
mmpy-option option, and a new comment on DEFAULT_arc_fpu_build
define. As for the last suggestion, my proposal is to have a latter
patch on the topic of .cpu, synced with a related binutils patch.

OK to apply?
Claudiu

gcc/
2016-05-09  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-arch.h: New file.
	* config/arc/arc-arches.def: Likewise.
	* config/arc/arc-cpus.def: Likewise.
	* config/arc/arc-options.def: Likewise.
	* config/arc/t-multilib: Likewise.
	* config/arc/genmultilib.awk: Likewise.
	* config/arc/genoptions.awk: Likewise.
	* config/arc/arc-tables.opt: Likewise.
	* config/arc/driver-arc.c: Likewise.
	* common/config/arc/arc-common.c (arc_handle_option): Trace
	toggled options.
	* config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra
	options; check for supported cpu against arc-cpus.def file.
	(arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define
	TARGET_CPU_BUILD macro; add driver-arc.o as an extra object.
	* config/arc/arc-c.def: Add emacs local variables.
	* config/arc/arc-opts.h (processor_type): Use arc-cpus.def file.
	(FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA)
	(FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL)
	(FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines.
	(DEFAULT_arc_fpu_build): Define.
	(DEFAULT_arc_mpy_option): Define.
	* config/arc/arc-protos.h (arc_init): Delete.
	* config/arc/arc.c (arc_cpu_name): New variable.
	(arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs)
	(arc_arc700, arc_arc600, arc_arc601): New variable.
	(arc_init): Add static; remove selection of default tune value,
	cleanup obsolete error messages.
	(arc_override_options): Make use of .def files for selecting the
	right cpu and option configurations.
	* config/arc/arc.h (stdbool.h): Include.
	(TARGET_CPU_DEFAULT): Define.
	(CPP_SPEC): Remove mcpu=NPS400 handling.
	(arc_cpu_to_as): Declare.
	(EXTRA_SPEC_FUNCTIONS): Define.
	(OPTION_DEFAULT_SPECS): Likewise.
	(ASM_DEFAULT): Remove.
	(ASM_SPEC): Use arc_cpu_to_as.
	(DRIVER_SELF_SPECS): Remove deprecated options.
	(arc_base_cpu):	Declare.
	(TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM)
	(TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_base_cpu
	variable.
	(MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT.
	* config/arc/arc.md (attr_cpu): Remove.
	* config/arc/arc.opt (mno-mpy): Deprecate.
	(mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM)
	(mcpu=ARCHS): Remove.
	(mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc):
	Deprecate.
	(mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove.
	(arc_fpu): Use new defines.
	(mpy-option): Change to use numeric or string like inputs.
	* config/arc/t-arc (driver-arc.o): New target.
	(arc-cpus, t-multilib, arc-tables.opt): Likewise.
	* config/arc/t-arc-newlib: Delete.
	* config/arc/t-arc-uClibc: Renamed to t-uClibc.
	* doc/invoke.texi (ARC): Update arc options.
---
 gcc/common/config/arc/arc-common.c |  69 ++++---------
 gcc/config.gcc                     |  47 +++++----
 gcc/config/arc/arc-arch.h          | 120 ++++++++++++++++++++++
 gcc/config/arc/arc-arches.def      |  56 ++++++++++
 gcc/config/arc/arc-c.def           |   4 +
 gcc/config/arc/arc-cpus.def        |  75 ++++++++++++++
 gcc/config/arc/arc-options.def     | 109 ++++++++++++++++++++
 gcc/config/arc/arc-opts.h          |  49 +++++++--
 gcc/config/arc/arc-protos.h        |   1 -
 gcc/config/arc/arc-tables.opt      |  90 ++++++++++++++++
 gcc/config/arc/arc.c               | 176 +++++++++++++++++---------------
 gcc/config/arc/arc.h               |  89 ++++++++--------
 gcc/config/arc/arc.md              |   5 -
 gcc/config/arc/arc.opt             | 169 +++++++++++++++---------------
 gcc/config/arc/driver-arc.c        |  78 ++++++++++++++
 gcc/config/arc/genmultilib.awk     | 203 +++++++++++++++++++++++++++++++++++++
 gcc/config/arc/genoptions.awk      |  86 ++++++++++++++++
 gcc/config/arc/t-arc               |  19 ++++
 gcc/config/arc/t-arc-newlib        |  46 ---------
 gcc/config/arc/t-arc-uClibc        |  20 ----
 gcc/config/arc/t-multilib          |  34 +++++++
 gcc/config/arc/t-uClibc            |  20 ++++
 gcc/doc/invoke.texi                |  90 +++++++++++++---
 23 files changed, 1277 insertions(+), 378 deletions(-)
 create mode 100644 gcc/config/arc/arc-arch.h
 create mode 100644 gcc/config/arc/arc-arches.def
 create mode 100644 gcc/config/arc/arc-cpus.def
 create mode 100644 gcc/config/arc/arc-options.def
 create mode 100644 gcc/config/arc/arc-tables.opt
 create mode 100644 gcc/config/arc/driver-arc.c
 create mode 100644 gcc/config/arc/genmultilib.awk
 create mode 100644 gcc/config/arc/genoptions.awk
 delete mode 100644 gcc/config/arc/t-arc-newlib
 delete mode 100644 gcc/config/arc/t-arc-uClibc
 create mode 100644 gcc/config/arc/t-multilib
 create mode 100644 gcc/config/arc/t-uClibc

diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index 5b687fb..1dbddae 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -2,6 +2,7 @@
    Copyright (C) 1994-2016 Free Software Foundation, Inc.
    Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
 		on behalf of Synopsys Inc.
+		Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
 
 This file is part of GCC.
 
@@ -61,17 +62,19 @@ static const struct default_options arc_option_optimization_table[] =
 
 /*  Process options.  */
 static bool
-arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
+arc_handle_option (struct gcc_options *opts,
+		   struct gcc_options *opts_set ATTRIBUTE_UNUSED,
 		   const struct cl_decoded_option *decoded,
 		   location_t loc)
 {
   size_t code = decoded->opt_index;
   int value = decoded->value;
   const char *arg = decoded->arg;
+  static int mcpu_seen = PROCESSOR_NONE;
+  char *p;
 
   switch (code)
     {
-      static int mcpu_seen = PROCESSOR_NONE;
     case OPT_mcpu_:
       /* N.B., at this point arc_cpu has already been set to its new value by
 	 our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless.  */
@@ -79,71 +82,33 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
       if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
 	warning_at (loc, 0, "multiple -mcpu= options specified.");
       mcpu_seen = value;
-
-      switch (value)
-	{
-	case PROCESSOR_NPS400:
-	  if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) )
-	    opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1;
-	  /* Fall through */
-	case PROCESSOR_ARC600:
-	case PROCESSOR_ARC700:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARC601:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARCHS:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags |= MASK_CODE_DENSITY;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags |= MASK_NORM_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags |= MASK_SWAP_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags |= MASK_DIVREM;	  /* Default: on.  */
-	  break;
-
-	case PROCESSOR_ARCEM:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags &= ~MASK_CODE_DENSITY;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags &= ~MASK_NORM_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags &= ~MASK_SWAP_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags &= ~MASK_DIVREM;	  /* Default: off.  */
-	  break;
-	default:
-	  gcc_unreachable ();
-	}
       break;
 
     case OPT_mmpy_option_:
-      if (value < 0 || value > 9)
-	error_at (loc, "bad value %qs for -mmpy-option switch", arg);
+      if (opts->x_arc_mpy_option == 1)
+	warning_at (loc, 0, "Unsupported value for mmpy-option");
+      break;
+
+    default:
       break;
     }
 
   return true;
 }
 
+#undef  TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
+
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
 #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
-#define TARGET_HANDLE_OPTION arc_handle_option
 
 #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
 
-/* We default to ARC700, which has the barrel shifter enabled.  */
-#define TARGET_DEFAULT_TARGET_FLAGS \
-  (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET)
 
+#undef  TARGET_HANDLE_OPTION
+#define TARGET_HANDLE_OPTION arc_handle_option
 
 #include "common/common-target-def.h"
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 8fd07c5..50dca89 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -318,6 +318,7 @@ arc*-*-*)
 	cpu_type=arc
 	c_target_objs="arc-c.o"
 	cxx_target_objs="arc-c.o"
+	extra_options="${extra_options} arc/arc-tables.opt"
 	;;
 arm*-*-*)
 	cpu_type=arm
@@ -991,13 +992,12 @@ alpha*-dec-*vms*)
 	;;
 arc*-*-elf*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
-	tmake_file="arc/t-arc-newlib arc/t-arc"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
+	tmake_file="arc/t-multilib arc/t-arc"
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -1014,15 +1014,14 @@ arc*-*-elf*)
 	;;
 arc*-*-linux-uclibc*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
-	tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc"
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
+	tmake_file="${tmake_file} arc/t-uClibc arc/t-arc"
 	tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0"
 	tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -3605,15 +3604,19 @@ case "${target}" in
 		done
 		;;
 
-	arc*-*-*) # was:	arc*-*-linux-uclibc)
+	arc*-*-*)
 		supported_defaults="cpu"
-		case $with_cpu in
-		  arc600|arc601|arc700)
-			;;
-		  *) echo "Unknown cpu type"
-			exit 1
-			;;
-		esac
+
+		if [ x"$with_cpu" = x ] \
+		    || grep "^ARC_CPU ($with_cpu," \
+		       ${srcdir}/config/arc/arc-cpus.def \
+		       > /dev/null; then
+		 # Ok
+		 true
+		else
+		 echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
+		 exit 1
+		fi
 		;;
 
 	arm*-*-*)
diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
new file mode 100644
index 0000000..7994543
--- /dev/null
+++ b/gcc/config/arc/arc-arch.h
@@ -0,0 +1,120 @@
+/* Definitions of types that are used to store ARC architecture and
+   device information.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu (claziss@synopsys.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ARC_ARCH_H
+#define GCC_ARC_ARCH_H
+
+#ifndef IN_LIBGCC2
+/* Architecture selection types.  */
+
+enum cpu_flags
+  {
+#define ARC_OPT(NAME, CODE, MASK, DOC)	    NAME = CODE,
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE,
+#include "arc-options.def"
+#undef ARC_OPT
+#undef ARC_OPTX
+    FL_END
+  };
+
+
+/* ARC architecture variants.  */
+
+enum base_architecture
+  {
+    BASE_ARCH_NONE,
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)  BASE_ARCH_##ARCH,
+#include "arc-arches.def"
+#undef ARC_ARCH
+    BASE_ARCH_END
+  };
+
+
+/* Tune variants.  Needs to match the attr_tune enum.  */
+
+enum arc_tune_attr
+  {
+    ARC_TUNE_NONE,
+    ARC_TUNE_ARC600,
+    ARC_TUNE_ARC700_4_2_STD,
+    ARC_TUNE_ARC700_4_2_XMAC
+  };
+
+/* CPU specific properties.  */
+
+typedef struct
+{
+  /* CPU name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* Specific flags.  */
+  const unsigned long long flags;
+
+  /* Tune value.  */
+  enum arc_tune_attr tune;
+} arc_cpu_t;
+
+
+/* Architecture specific propoerties.  */
+
+typedef struct
+{
+  /* Architecture name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* All allowed flags for this architecture.  */
+  const unsigned long long flags;
+
+  /* Default flags for this architecture.  It is a subset of
+     FLAGS.  */
+  const unsigned long long dflags;
+} arc_arch_t;
+
+
+
+const arc_arch_t arc_arch_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, 0},
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)	\
+    {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS},
+#include "arc-arches.def"
+#undef ARC_ARCH
+    {NULL, BASE_ARCH_END, 0, 0}
+  };
+
+const arc_cpu_t arc_cpu_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE},
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
+    {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE},
+#include "arc-cpus.def"
+#undef ARC_CPU
+    {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE}
+  };
+
+#endif
+#endif /* GCC_ARC_ARCH_H */
diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
new file mode 100644
index 0000000..f24babb
--- /dev/null
+++ b/gcc/config/arc/arc-arches.def
@@ -0,0 +1,56 @@
+/* ARC ARCH architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of all known ARC base architectures.  These defines are used
+   to check if command line given options are valid for a specific
+   architecture, and to set default architecture options, if needed.
+
+   Before including this file, define a macro:
+
+   ARC_ARCH (NAME, ARCH, DEV_HW_FACILITIES, DEF_HW_FACILITIES)
+
+   where the arguments are the fields of arc_arch_t:
+
+   NAME			Architecture given name;
+
+   ARCH			Architecture class as in enum base_architecture;
+
+   DEV_HW_FACILITIES	All allowed architecture hardware facilities.
+			These facilities are represented as compiler
+			options, defined in arc_options.def file.
+
+   DEF_HW_FACILITIES	Default flags for this architecture.  It is a
+			subset of DEV_HW_FACILITIES.  */
+
+ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
+	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
+	  | FL_SIMD | FL_FPUDA, 0)
+ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
+	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
+	  | FL_FPUS | FL_FPUD,						\
+	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
+ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
+	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
+ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
+	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
+	  FL_BS | FL_NORM | FL_SWAP)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
index 065e973..4cfd7b6 100644
--- a/gcc/config/arc/arc-c.def
+++ b/gcc/config/arc/arc-c.def
@@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__",     TARGET_EM)
 ARC_C_DEF ("__HS__",     TARGET_HS)
 ARC_C_DEF ("__Xnorm",    TARGET_NORM)
 ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
new file mode 100644
index 0000000..0ceb734
--- /dev/null
+++ b/gcc/config/arc/arc-cpus.def
@@ -0,0 +1,75 @@
+/* ARC CPU architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of various ARC CPU configurations.  If updated, cd to
+   $(builddir)/gcc and run
+
+   $ make arc-cpus
+
+   This will regenerate / update the following source files:
+
+   -  $(srcdir)/config/arc/t-multilib
+   -  $(srcdir)/config/arc/arc-tables.opt
+
+   After that, rebuild everything and check-in the new sources to the
+   repo.  This file defines the accepted values for -mcpu=<CPU>
+   option.
+
+   Before including this file, define a macro:
+
+   ARC_CPU (NAME, ARCH, FLAGS, TUNE)
+
+   where the arguments are the fields of arc_cpu_t:
+
+   NAME	  A given arbitrary name.
+   ARCH	  Base architecture for the given CPU.
+   FLAGS  Specific hardware flags that are enabled by this CPU configuration,
+	  as defined in arc-options.def file, and allowed by arc-arches.def
+	  file.  The specific hardware flags are enumerated without using
+	  spaces between the '|' character and consequtive flags.
+   TUNE	  Tune value for the given configuration, otherwise NONE.  */
+
+ARC_CPU (em,	    em, 0, NONE)
+ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
+ARC_CPU (em4,	    em, FL_CD, NONE)
+ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
+ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
+ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
+
+ARC_CPU (hs,	     hs, 0, NONE)
+ARC_CPU (archs,	     hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs34,	     hs, FL_MPYOPT_2, NONE)
+ARC_CPU (hs38,	     hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE)
+
+ARC_CPU (arc600,	  6xx, FL_BS, ARC600)
+ARC_CPU (arc600_norm,	  6xx, FL_BS|FL_NORM, ARC600)
+ARC_CPU (arc600_mul64,	  6xx, FL_BS|FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600)
+ARC_CPU (arc601,	  6xx, 0, ARC600)
+ARC_CPU (arc601_norm,	  6xx, FL_NORM, ARC600)
+ARC_CPU (arc601_mul64,	  6xx, FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600)
+
+ARC_CPU (arc700, 700, 0, ARC700_4_2_STD)
+ARC_CPU (nps400, 700, 0, ARC700_4_2_STD)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
new file mode 100644
index 0000000..0f9d36c
--- /dev/null
+++ b/gcc/config/arc/arc-options.def
@@ -0,0 +1,109 @@
+/* ARC options.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of all known ARC hardware modifier options (i.e., compiler
+   options that are selecting a hardware facility).  There can be two
+   types options: simple switches (e.g. code-density option can be
+   on/off), or can accept multiple values (e.g., fpu options).
+
+   For any valid HW option, define a macro:
+
+   ARC_OPT (NAME, CODE, MASK, DOC)
+
+   where:
+   NAME	  Name (identifier) of a particular hardware modifier option,
+	  as in enum cpu_flags.
+
+   CODE	  64-bit mask used to encode NAME.
+
+   MASK	  Corresponding GCC's MASK_<option> macro.
+
+   DOC	  A string used when emitting compiler errors or warnings.
+
+   For a multi-value option, define a macro for a valid value:
+
+   ARC_OPTX (NAME, CODE, VAR, VAL, DOC)
+
+   where:
+   NAME	  Name (identifier) of a particular hardware modifier
+	  configuration.
+
+   CODE	  64-bit mask used to encode NAME.  It will be encoded in the
+	  same variable like options given via ARC_OPT.
+
+   VAR	  Corresponding GCC's option variable.
+
+   VAL	  Value to be set in VAR.
+
+   DOC	  A string used when emitting compiler errors or warnings.
+
+   All multi-value options are defined using ARC_OPTX and ARC_OPT.
+   ARC_OPT contains a mask with all valid values for the given
+   option.  */
+
+ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
+ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
+ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
+
+ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
+ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
+ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
+ARC_OPT (FL_SWAP,     (1ULL << 7), MASK_SWAP_SET,	   "swap")
+ARC_OPT (FL_MUL64,    (1ULL << 8), MASK_MUL64_SET,	   "mul64")
+ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16")
+
+ARC_OPT (FL_EA,	      (1ULL << 11), MASK_EA_SET,	   "extended arithmetics")
+ARC_OPT (FL_SPFP,     (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX")
+ARC_OPT (FL_DPFP,     (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX")
+ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET,	   "argonaut")
+ARC_OPT (FL_SIMD,     (1ULL << 15), MASK_SIMD_SET,	   "simd")
+
+ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w")
+ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1")
+ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2")
+ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3")
+ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4")
+ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5")
+ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy")
+ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd")
+ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw")
+
+ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option")
+ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option")
+
+ARC_OPTX (FL_FPU_FPUS,	    (1ULL << 26), arc_fpu_build, FPU_FPUS,	"mfpu=fpus")
+ARC_OPTX (FL_FPU_FPUS_DIV,  (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV,	"mfpu=fpus_div")
+ARC_OPTX (FL_FPU_FPUS_FMA,  (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA,	"mfpu=fpus_fma")
+ARC_OPTX (FL_FPU_FPUS_ALL,  (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL,	"mfpu=fpus_all")
+ARC_OPTX (FL_FPU_FPUDA,	    (1ULL << 30), arc_fpu_build, FPU_FPUDA,	"mfpu=fpuda")
+ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div")
+ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma")
+ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all")
+ARC_OPTX (FL_FPU_FPUD,	    (1ULL << 34), arc_fpu_build, FPU_FPUD,	"mfpu=fpud")
+ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV,	"mfpu=fpud_div")
+ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA,	"mfpu=fpud_fma")
+ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL,	"mfpu=fpud_all")
+
+ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
+ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
+ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
index cbd7898..e5bca84 100644
--- a/gcc/config/arc/arc-opts.h
+++ b/gcc/config/arc/arc-opts.h
@@ -18,15 +18,16 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef ARC_OPTS_H
+#define ARC_OPTS_H
+
 enum processor_type
 {
-  PROCESSOR_NONE,
-  PROCESSOR_ARC600,
-  PROCESSOR_ARC601,
-  PROCESSOR_ARC700,
-  PROCESSOR_NPS400,
-  PROCESSOR_ARCEM,
-  PROCESSOR_ARCHS
+  PROCESSOR_NONE = 0,
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)  PROCESSOR_##NAME,
+#include "arc-cpus.def"
+#undef ARC_CPU
+  PROCESSOR_generic
 };
 
 /* Single precision floating point.  */
@@ -48,3 +49,37 @@ enum processor_type
 /* Double precision floating point assist operations.  */
 #define FPX_DP    0x0100
 
+/* fpus option combi.  */
+#define FPU_FPUS  (FPU_SP | FPU_SC)
+/* fpud option combi.  */
+#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+/* fpuda option combi.  */
+#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
+/* fpuda_div option combi.  */
+#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+/* fpuda_fma option combi.  */
+#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+/* fpuda_all option combi.  */
+#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+/* fpus_div option combi.  */
+#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
+/* fpus_fma option combi.  */
+#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
+/* fpus_all option combi.  */
+#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+/* fpud_div option combi.  */
+#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
+/* fpud_fma option combi.  */
+#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
+/* fpud_all option combi.  */
+#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+
+/* Default FPU option value needed to mark if the variable in question
+   is changed by a command line option or not.  This is required when
+   we set the cpu's specific configuration.  */
+#define DEFAULT_arc_fpu_build 0x10000000
+
+/* Default MPY option value.  */
+#define DEFAULT_arc_mpy_option -1
+
+#endif /* ARC_OPTS_H */
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index ad5d4d3..d1266b4 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
 #endif /* TREE_CODE */
 
 
-extern void arc_init (void);
 extern unsigned int arc_compute_frame_size (int);
 extern bool arc_ccfsm_branch_deleted_p (void);
 extern void arc_ccfsm_record_branch_deleted (void);
diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
new file mode 100644
index 0000000..0e7c50c
--- /dev/null
+++ b/gcc/config/arc/arc-tables.opt
@@ -0,0 +1,90 @@
+; Auto-generated Makefile Snip
+; Generated by    : ./gcc/config/arc/genoptions.awk
+; Generated from  : ./gcc/config/arc/arc-cpu.def
+;
+; Copyright (C) 2016 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+Enum
+Name(processor_type) Type(enum processor_type)
+Known ARC CPUs (for use with the -mcpu= option):
+
+EnumValue
+Enum(processor_type) String(em) Value(PROCESSOR_em)
+
+EnumValue
+Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
+
+EnumValue
+Enum(processor_type) String(em4) Value(PROCESSOR_em4)
+
+EnumValue
+Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips)
+
+EnumValue
+Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
+
+EnumValue
+Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
+
+EnumValue
+Enum(processor_type) String(hs) Value(PROCESSOR_hs)
+
+EnumValue
+Enum(processor_type) String(archs) Value(PROCESSOR_archs)
+
+EnumValue
+Enum(processor_type) String(hs34) Value(PROCESSOR_hs34)
+
+EnumValue
+Enum(processor_type) String(hs38) Value(PROCESSOR_hs38)
+
+EnumValue
+Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux)
+
+EnumValue
+Enum(processor_type) String(arc600) Value(PROCESSOR_arc600)
+
+EnumValue
+Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm)
+
+EnumValue
+Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64)
+
+EnumValue
+Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc601) Value(PROCESSOR_arc601)
+
+EnumValue
+Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm)
+
+EnumValue
+Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64)
+
+EnumValue
+Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc700) Value(PROCESSOR_arc700)
+
+EnumValue
+Enum(processor_type) String(nps400) Value(PROCESSOR_nps400)
+
+
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 5e8d6b4..8810e91 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -64,7 +64,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 
 /* Which cpu we're compiling for (ARC600, ARC601, ARC700).  */
-static const char *arc_cpu_string = "";
+static char arc_cpu_name[10] = "";
+static const char *arc_cpu_string = arc_cpu_name;
 
 /* ??? Loads can handle any constant, stores can only handle small ones.  */
 /* OTOH, LIMMs cost extra, so their usefulness is limited.  */
@@ -241,6 +242,12 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
 						enum by_pieces_operation op,
 						bool);
 
+static const arc_cpu_t *arc_selected_cpu;
+static const arc_arch_t *arc_selected_arch;
+
+/* Global var which sets the current compilation architecture.  */
+enum base_architecture arc_base_cpu;
+
 /* Implements target hook vector_mode_supported_p.  */
 
 static bool
@@ -668,47 +675,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
 
 /* Called by OVERRIDE_OPTIONS to initialize various things.  */
 
-void
+static void
 arc_init (void)
 {
-  enum attr_tune tune_dflt = TUNE_NONE;
-
-  switch (arc_cpu)
-    {
-    case PROCESSOR_ARC600:
-      arc_cpu_string = "ARC600";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC601:
-      arc_cpu_string = "ARC601";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC700:
-      arc_cpu_string = "ARC700";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_NPS400:
-      arc_cpu_string = "NPS400";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_ARCEM:
-      arc_cpu_string = "EM";
-      break;
-
-    case PROCESSOR_ARCHS:
-      arc_cpu_string = "HS";
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  if (arc_tune == TUNE_NONE)
-    arc_tune = tune_dflt;
   /* Note: arc_multcost is only used in rtx_cost if speed is true.  */
   if (arc_multcost < 0)
     switch (arc_tune)
@@ -739,18 +708,10 @@ arc_init (void)
 	break;
       }
 
-  /* Support mul64 generation only for ARC600.  */
-  if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul64 not supported for ARC700 or ARCv2");
-
   /* MPY instructions valid only for ARC700 or ARCv2.  */
   if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
       error ("-mno-mpy supported only for ARC700 or ARCv2");
 
-  /* mul/mac instructions only for ARC600.  */
-  if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul32x16 supported only for ARC600 or ARC601");
-
   if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
       error ("-mno-dpfp-lrsr supported only with -mdpfp");
 
@@ -763,23 +724,11 @@ arc_init (void)
   if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
     error ("-mspfp_fast not available on ARC600 or ARC601");
 
-  /* FPX-3. No FPX extensions on pre-ARC600 cores.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
-    error ("FPX extensions not available on pre-ARC600 cores");
-
-  /* FPX-4.  No FPX extensions mixed with FPU extensions for ARC HS
-     cpus.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && TARGET_HARD_FLOAT
-      && TARGET_HS)
+  /* FPX-4.  No FPX extensions mixed with FPU extensions.  */
+  if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
+      && TARGET_HARD_FLOAT)
     error ("No FPX/FPU mixing allowed");
 
-  /* Only selected multiplier configurations are available for HS.  */
-  if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
-		    || (arc_mpy_option == 1)))
-    error ("This multiplier configuration is not available for HS cores");
-
   /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic.  */
   if (flag_pic && TARGET_ARC600_FAMILY)
     {
@@ -789,26 +738,6 @@ arc_init (void)
       flag_pic = 0;
     }
 
-  if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS))
-    error ("-matomic is only supported for ARC700 or ARC HS cores");
-
-  /* ll64 ops only available for HS.  */
-  if (TARGET_LL64 && !TARGET_HS)
-    error ("-mll64 is only supported for ARC HS cores");
-
-  /* FPU support only for V2.  */
-  if (TARGET_HARD_FLOAT)
-    {
-      if (TARGET_EM
-	  && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
-	error ("FPU double precision options are available for ARC HS only");
-      if (TARGET_HS && (arc_fpu_build & FPX_DP))
-	error ("FPU double precision assist "
-	       "options are not available for ARC HS");
-      if (!TARGET_HS && !TARGET_EM)
-	error ("FPU options are available for ARCv2 architecture only");
-    }
-
   arc_init_reg_tables ();
 
   /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
@@ -853,7 +782,86 @@ static void
 arc_override_options (void)
 {
   if (arc_cpu == PROCESSOR_NONE)
-    arc_cpu = PROCESSOR_ARC700;
+    arc_cpu = TARGET_CPU_DEFAULT;
+
+  /* Set the default cpu options.  */
+  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
+  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
+  arc_base_cpu = arc_selected_arch->arch;
+
+  /* Set the architectures.  */
+  switch (arc_selected_arch->arch)
+    {
+    case BASE_ARCH_em:
+      arc_cpu_string = "EM";
+      break;
+    case BASE_ARCH_hs:
+      arc_cpu_string = "HS";
+      break;
+    case BASE_ARCH_700:
+      arc_cpu_string = "ARC700";
+      break;
+    case BASE_ARCH_6xx:
+      arc_cpu_string = "ARC600";
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
+     specific flags are set in arc-common.c.  The architecture forces
+     the default hardware configurations in, regardless what command
+     line options are saying.  The CPU optional hw options can be
+     turned on or off.  */
+#define ARC_OPT(NAME, CODE, MASK, DOC)			\
+  do {							\
+    if ((arc_selected_cpu->flags & CODE)		\
+	&& ((target_flags_explicit & MASK) == 0))	\
+      target_flags |= MASK;				\
+    if (arc_selected_arch->dflags & CODE)		\
+      target_flags |= MASK;				\
+  } while (0);
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
+  do {						\
+    if ((arc_selected_cpu->flags & CODE)	\
+	&& (VAR == DEFAULT_##VAR))		\
+      VAR = VAL;				\
+    if (arc_selected_arch->dflags & CODE)	\
+      VAR = VAL;				\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Check options against architecture options.  Throw an error if
+     option is not allowed.  */
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
+  do {								\
+    if ((VAR == VAL)						\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      {								\
+	error ("%s is not available for %s architecture",	\
+	       DOC, arc_selected_arch->name);			\
+      }								\
+  } while (0);
+#define ARC_OPT(NAME, CODE, MASK, DOC)				\
+  do {								\
+    if ((target_flags & MASK)					\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      error ("%s is not available for %s architecture",		\
+	     DOC, arc_selected_arch->name);			\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Set Tune option.  */
+  if (arc_tune == TUNE_NONE)
+    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
 
   if (arc_size_opt_level == 3)
     optimize_size = 1;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index c02e1cd..0f97afc 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ARC_H
 #define GCC_ARC_H
 
+#include <stdbool.h>
+
 /* Things to do:
 
    - incscc, decscc?
@@ -39,6 +41,10 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
 #define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
 
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT	PROCESSOR_arc700
+#endif
+
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)	\
 	((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
@@ -74,9 +80,11 @@ along with GCC; see the file COPYING3.  If not see
       GNU_USER_TARGET_OS_CPP_BUILTINS (); \
     } \
   while (0)
-#endif
 
-/* Match the macros used in the assembler.  */
+#endif /* DEFAULT_LIBC == LIBC_UCLIBC */
+
+/* Macros enabled by specific command line option.  FIXME: to be
+   deprecatd.  */
 #define CPP_SPEC "\
 %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \
 %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \
@@ -85,34 +93,22 @@ along with GCC; see the file COPYING3.  If not see
 %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \
 %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \
 %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \
-%{mcpu=NPS400:-D__NPS400__} \
-%{mcpu=nps400:-D__NPS400__} \
-"
+%{mcpu=nps400:-D__NPS400__}"
 
 #define CC1_SPEC "\
 %{EB:%{EL:%emay not use both -EB and -EL}} \
 %{EB:-mbig-endian} %{EL:-mlittle-endian} \
 "
+extern const char *arc_cpu_to_as (int argc, const char **argv);
+
+#define EXTRA_SPEC_FUNCTIONS			\
+  { "cpu_to_as", arc_cpu_to_as },
+
+#define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "			\
+  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
 
-#define ASM_DEFAULT "-mARC700 -mEA"
-
-#define ASM_SPEC  "\
-%{mbig-endian|EB:-EB} %{EL} \
-%{mcpu=ARC600:-mARC600} \
-%{mcpu=ARC601:-mARC601} \
-%{mcpu=ARC700:-mARC700} \
-%{mcpu=ARC700:-mEA} \
-%{!mcpu=*:" ASM_DEFAULT "} \
-%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \
-%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \
-%{msimd} \
-%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \
-%{mcpu=ARC700|!mcpu=*:%{mlock}} \
-%{mcpu=ARC700|!mcpu=*:%{mswape}} \
-%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \
-%{mcpu=ARCHS:-mHS} \
-%{mcpu=ARCEM:-mEM} \
-%{matomic:-mlock}"
+#define OPTION_DEFAULT_SPECS						\
+  {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
 
 #if DEFAULT_LIBC == LIBC_UCLIBC
 /* Note that the default is to link against dynamic libraries, if they are
@@ -196,17 +192,11 @@ along with GCC; see the file COPYING3.  If not see
 #define TARGET_MMEDIUM_CALLS_DEFAULT 0
 #endif
 
-#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \
-  "%{mARC600|mA6: -mcpu=ARC600 %<mARC600 %<mA6}" \
-  "%{mARC601: -mcpu=ARC601 %<mARC601}" \
-  "%{mARC700|mA7: -mcpu=ARC700 %<mARC700 %<mA7}" \
-  "%{mbarrel_shifte*: -mbarrel-shifte%* %<mbarrel_shifte*}" \
-  "%{mEA: -mea %<mEA}" \
-  "%{mspfp_*: -mspfp-%* %<mspfp_*}" \
-  "%{mdpfp_*: -mdpfp-%* %<mdpfp_*}" \
-  "%{mdsp_pack*: -mdsp-pack%* %<mdsp_pack*}" \
-  "%{mmac_*: -mmac-%* %<mmac_*}" \
-  "%{multcost=*: -mmultcost=%* %<multcost=*}"
+#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS		   \
+  "%{mARC600|mA6: -mcpu=arc600 %<mARC600 %<mA6 %<mARC600}"	   \
+  "%{mARC601: -mcpu=arc601 %<mARC601}"				   \
+  "%{mARC700|mA7: -mcpu=arc700 %<mARC700 %<mA7}"		   \
+  "%{mEA: -mea %<mEA}"
 
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
@@ -252,20 +242,21 @@ along with GCC; see the file COPYING3.  If not see
    use conditional execution?  */
 #define TARGET_AT_DBR_CONDEXEC  (!TARGET_ARC700 && !TARGET_V2)
 
-#define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
-#define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
-#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700	\
-		       || arc_cpu == PROCESSOR_NPS400)
-#define TARGET_EM     (arc_cpu == PROCESSOR_ARCEM)
-#define TARGET_HS     (arc_cpu == PROCESSOR_ARCHS)
-#define TARGET_V2							\
-  ((arc_cpu == PROCESSOR_ARCHS) || (arc_cpu == PROCESSOR_ARCEM))
-
-/* Recast the cpu class to be the cpu attribute.  */
-#define arc_cpu_attr ((enum attr_cpu)arc_cpu)
-
-#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mARC700" }
+extern enum base_architecture arc_base_cpu;
+
+#define TARGET_ARC600 ((arc_base_cpu == BASE_ARCH_6xx)	\
+		       && (TARGET_BARREL_SHIFTER))
+#define TARGET_ARC601 ((arc_base_cpu == BASE_ARCH_6xx)	\
+		       && (!TARGET_BARREL_SHIFTER))
+#define TARGET_ARC700 (arc_base_cpu == BASE_ARCH_700)
+#define TARGET_EM (arc_base_cpu == BASE_ARCH_em)
+#define TARGET_HS (arc_base_cpu == BASE_ARCH_hs)
+#define TARGET_V2 (TARGET_EM || TARGET_HS)
+
+#ifdef ARC_MULTILIB_CPU_DEFAULT
+# ifndef MULTILIB_DEFAULTS
+#  define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT }
+# endif
 #endif
 
 #ifndef UNALIGNED_ACCESS_DEFAULT
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 715da31..6f757b6 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -231,11 +231,6 @@
 	 (eq_attr "is_CALL" "yes") (const_string "yes")]
 	(const_string "no")))
 
-
-;; Attribute describing the processor
-(define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
-  (const (symbol_ref "arc_cpu_attr")))
-
 ;; true for compact instructions (those with _s suffix)
 ;; "maybe" means compact unless we conditionalize the insn.
 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 4caf366..5685100 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -54,8 +54,74 @@ Target Report
 Same as -mA7.
 
 mmpy-option=
-Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
--mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
+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)
@@ -100,7 +166,7 @@ Target Report Mask(MUL64_SET)
 Generate mul64 and mulu64 instructions.
 
 mno-mpy
-Target Report Mask(NOMPY_SET)
+Target Report Mask(NOMPY_SET) Warn(%qs is deprecated)
 Do not generate mpy instructions for ARC700.
 
 mea
@@ -167,45 +233,6 @@ mcpu=
 Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
 -mcpu=CPU	Compile code for ARC variant CPU.
 
-Enum
-Name(processor_type) Type(enum processor_type)
-
-EnumValue
-Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(arc600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(arc601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(arcem) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(ARCHS) Value(PROCESSOR_ARCHS)
-
-EnumValue
-Enum(processor_type) String(archs) Value(PROCESSOR_ARCHS)
-
 msize-level=
 Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
 size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os.
@@ -308,25 +335,25 @@ Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
 ; Flags used by the assembler, but for which we define preprocessor
 ; macro symbols as well.
 mcrc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable variable polynomial CRC extension.
 
 mdsp-packa
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable DSP 3.1 Pack A extensions.
 
 mdvbf
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable dual viterbi butterfly extension.
 
 mmac-d16
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mmac-24
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mtelephony
-Target Report RejectNegative
+Target Report RejectNegative Warn(%qs is deprecated)
 Enable Dual and Single Operand Instructions for Telephony.
 
 mxy
@@ -343,7 +370,7 @@ Target Report
 Enable swap byte ordering extension instruction.
 
 mrtsc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable 64-bit Time-Stamp Counter extension instruction.
 
 EB
@@ -394,24 +421,6 @@ Target
 multcost=
 Target RejectNegative Joined
 
-; Unfortunately, listing the full option name gives us clashes
-; with OPT_opt_name being claimed for both opt_name and opt-name,
-; so we leave out the last character or more.
-mbarrel_shifte
-Target Joined
-
-mspfp_
-Target Joined
-
-mdpfp_
-Target Joined
-
-mdsp_pack
-Target Joined
-
-mmac_
-Target Joined
-
 matomic
 Target Report Mask(ATOMIC)
 Enable atomic instructions.
@@ -421,47 +430,47 @@ Target Report Mask(LL64)
 Enable double load/store instructions for ARC HS.
 
 mfpu=
-Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
+Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(DEFAULT_arc_fpu_build)
 Specify the name of the target floating point configuration.
 
 Enum
 Name(arc_fpu) Type(int)
 
 EnumValue
-Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
+Enum(arc_fpu) String(fpus) Value(FPU_FPUS)
 
 EnumValue
-Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+Enum(arc_fpu) String(fpud) Value(FPU_FPUD)
 
 EnumValue
-Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
+Enum(arc_fpu) String(fpuda) Value(FPU_FPUDA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_div) Value(FPU_FPUDA_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+Enum(arc_fpu) String(fpuda_fma) Value(FPU_FPUDA_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_all) Value(FPU_FPUDA_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
+Enum(arc_fpu) String(fpus_div) Value(FPU_FPUS_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
+Enum(arc_fpu) String(fpud_div) Value(FPU_FPUD_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
+Enum(arc_fpu) String(fpus_fma) Value(FPU_FPUS_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
+Enum(arc_fpu) String(fpud_fma) Value(FPU_FPUD_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+Enum(arc_fpu) String(fpus_all) Value(FPU_FPUS_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL)
 
 mtp-regno=
 Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25)
diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
new file mode 100644
index 0000000..6117968
--- /dev/null
+++ b/gcc/config/arc/driver-arc.c
@@ -0,0 +1,78 @@
+/* Subroutines for the gcc driver.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu <claziss@synopsys.com>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+/* Returns command line parameters to pass to as.  */
+
+const char*
+arc_cpu_to_as (int argc, const char **argv)
+{
+  const char *name = NULL;
+  const arc_cpu_t *arc_selected_cpu;
+
+  /* No argument, check what is the default cpu.  */
+  if (argc == 0)
+    {
+      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
+    }
+  else
+    {
+      name = argv[0];
+      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
+	   arc_selected_cpu++)
+	{
+	  if (strcmp (arc_selected_cpu->name, name) == 0)
+	    break;
+	}
+    }
+
+  switch (arc_selected_cpu->arch)
+    {
+    case BASE_ARCH_em:
+      if (arc_selected_cpu->flags & FL_CD)
+	name = "-mcode-density";
+      else
+	name = "";
+      if (arc_selected_cpu->flags & FL_FPUDA)
+	name = concat ("-mfpuda ", name, NULL);
+      if (arc_selected_cpu->flags & FL_SPFP)
+	name = concat ("-mspfp ", name, NULL);
+      if (arc_selected_cpu->flags & FL_DPFP)
+	name = concat ("-mdpfp ", name, NULL);
+      return concat ("-mcpu=arcem ", name, NULL);
+    case BASE_ARCH_hs:
+      return "-mcpu=archs";
+    case BASE_ARCH_700:
+      return "-mcpu=arc700 -mEA";
+    case BASE_ARCH_6xx:
+      if (arc_selected_cpu->flags & FL_MUL64)
+	return "-mcpu=arc600 -mmul64 -mnorm";
+      if (arc_selected_cpu->flags & FL_MUL32x16)
+	return "-mcpu=arc600 -mdsp-packa -mnorm";
+      return "-mcpu=arc600 -mnorm";
+    default:
+      gcc_unreachable ();
+    }
+  return NULL;
+}
diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
new file mode 100644
index 0000000..5934f4f
--- /dev/null
+++ b/gcc/config/arc/genmultilib.awk
@@ -0,0 +1,203 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+# Transform CPU Information from arc-cpu.def to a
+# Representation that is understood by GCC's multilib Machinery.
+#
+# The Script works as a Filter from STDIN to STDOUT.
+#
+# FORMAT = "Makefile": Generate Makefile Snipet that sets some
+#                      MULTILIB_* Variables as needed.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+  n_reuse = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "# Auto-generated Makefile Snip"
+	  print "# Generated by    : ./gcc/config/arc/genmultilib.awk"
+	  print "# Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print "# Used by         : tmake_file from Makefile and genmultilib"
+	  print ""
+	}
+    }
+
+  comment = 2;
+
+  print
+}
+
+/^$/ {
+  # The first empty line stops copy-pasting the GPL comments
+  # from this file to the generated file.
+
+  comment = 0
+}
+
+
+/^ARC_CPU/ {
+  name = $2
+  #  gsub ("\"", "", name)
+
+  if ($4 != "0")
+    {
+      arch = $3
+      if (arch == "6xx")
+	arch = 601
+
+      n = split ($4, cpu_flg, "|")
+
+      line = "mcpu." arch
+      for (i = 1; i <= n; i++)
+	{
+	  if (cpu_flg[i] == "FL_MPYOPT_0")
+	    line = line "/mmpy-option.0"
+	  else if (cpu_flg[i] == "FL_MPYOPT_1")
+	    line = line "/mmpy-option.1"
+	  else if (cpu_flg[i] == "FL_MPYOPT_2")
+	    line = line "/mmpy-option.2"
+	  else if (cpu_flg[i] == "FL_MPYOPT_3")
+	    line = line "/mmpy-option.3"
+	  else if (cpu_flg[i] == "FL_MPYOPT_4")
+	    line = line "/mmpy-option.4"
+	  else if (cpu_flg[i] == "FL_MPYOPT_5")
+	    line = line "/mmpy-option.5"
+	  else if (cpu_flg[i] == "FL_MPYOPT_6")
+	    line = line "/mmpy-option.6"
+	  else if (cpu_flg[i] == "FL_MPYOPT_7")
+	    line = line "/mmpy-option.7"
+	  else if (cpu_flg[i] == "FL_MPYOPT_8")
+	    line = line "/mmpy-option.8"
+	  else if (cpu_flg[i] == "FL_MPYOPT_9")
+	    line = line "/mmpy-option.9"
+	  else if (cpu_flg[i] == "FL_CD")
+	    line = line "/mcode-density"
+	  else if (cpu_flg[i] == "FL_BS")
+	    line = line "/mbarrel-shifter"
+	  else if (cpu_flg[i] == "FL_DIVREM")
+	    line = line "/mdiv-rem"
+	  else if (cpu_flg[i] == "FL_NORM" \
+		   || cpu_flg[i] == "FL_SWAP")
+	    line = line "/mnorm"
+	  else if (cpu_flg[i] == "FL_FPU_FPUS")
+	    line = line "/mfpu.fpus"
+	  else if (cpu_flg[i] == "FL_FPU_FPUDA")
+	    line = line "/mfpu.fpuda"
+	  else if (cpu_flg[i] == "FL_FPU_FPUD_ALL")
+	    line = line "/mfpu.fpud_all"
+	  else if (cpu_flg[i] == "FL_LL64")
+	    line = line "/mll64"
+	  else if (cpu_flg[i] == "FL_MUL64")
+	    line = line "/mmul64"
+	  else if (cpu_flg[i] == "FL_MUL32x16")
+	    line = line "/mmul32x16"
+	  else if (cpu_flg[i] == "FL_FPX_QUARK")
+	    line = line "/quark"
+	  else if (cpu_flg[i] == "FL_SPFP")
+	    line = line "/spfp"
+	  else if (cpu_flg[i] == "FL_DPFP")
+	    line = line "/dpfp"
+	  else
+	    {
+	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
+	      exit 1
+	    }
+	}
+      line = "mcpu." name "=" line
+      reuse[n_reuse] = line
+      n_reuse++
+    }
+
+  core = name
+  cores[n_cores] = core
+  n_cores++
+}
+
+##################################################################
+#
+# We gathered all the Information, now build/output the following:
+#
+#    awk Variable         target Variable          FORMAT
+#  -----------------------------------------------------------
+#    m_options     <->    MULTILIB_OPTIONS         Makefile
+#    m_dirnames    <->    MULTILIB_DIRNAMES           "
+#
+##################################################################
+
+END {
+  m_options    = "\nMULTILIB_OPTIONS = "
+  m_dirnames   = "\nMULTILIB_DIRNAMES ="
+  m_reuse      = "\nMULTILIB_REUSE ="
+
+  sep = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options  = m_options sep "mcpu=" cores[c]
+      m_dirnames = m_dirnames " " cores[c]
+      sep = "/"
+    }
+
+  sep = ""
+  for (c = 0; c < n_reuse; c++)
+    {
+      m_reuse = m_reuse sep reuse[c]
+      sep = "\nMULTILIB_REUSE +="
+    }
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+      # Intended Target: ./gcc/config/arc/t-multilib
+
+      print m_options
+      print m_dirnames
+
+      ############################################################
+      # Legacy Aliases
+      ############################################################
+
+      print ""
+      print "# Aliases:"
+      print "MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mA6"
+      print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601"
+      print "MULTILIB_MATCHES += mcpu?arc700=mA7"
+      print "MULTILIB_MATCHES += mcpu?arc700=mARC700"
+    }
+}
diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk
new file mode 100644
index 0000000..24a93eb
--- /dev/null
+++ b/gcc/config/arc/genoptions.awk
@@ -0,0 +1,86 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "; Auto-generated Makefile Snip"
+	  print "; Generated by    : ./gcc/config/arc/genoptions.awk"
+	  print "; Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print ";"
+	}
+    }
+
+  comment = 2;
+
+  gsub ("^#", ";", $0)
+  print
+}
+
+/^$/ {
+    # The first empty line stops copy-pasting the GPL comments
+    # from this file to the generated file.
+    comment = 0
+}
+
+/^ARC_CPU/ {
+  name = $2
+  cores[n_cores] = name;
+  n_cores++
+}
+
+END {
+  m_option = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options = m_options "EnumValue\nEnum(processor_type) String(" \
+	cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n"
+    }
+
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+	print "\nEnum"
+	print "Name(processor_type) Type(enum processor_type)"
+	print "Known ARC CPUs (for use with the -mcpu= option):\n"
+	print m_options
+    }
+}
diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
index 4252e73..bdb1328 100644
--- a/gcc/config/arc/t-arc
+++ b/gcc/config/arc/t-arc
@@ -19,11 +19,30 @@
 
 TM_H += $(srcdir)/config/arc/arc-c.def
 
+driver-arc.o: $(srcdir)/config/arc/driver-arc.c \
+  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
 arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \
 $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arc/arc-c.c
 
+#Run `arc-cpus` if you changed something in arc-cpus.def
+
+.PHONY: arc-cpus
+
+arc-cpus: $(srcdir)/config/arc/t-multilib \
+	$(srcdir)/config/arc/arc-tables.opt
+
+$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk 	\
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
+$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
 # Local Variables:
 # mode: Makefile
 # End:
diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib
deleted file mode 100644
index c49a3fcc..0000000
--- a/gcc/config/arc/t-arc-newlib
+++ /dev/null
@@ -1,46 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm
-MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm
-#
-# Aliases:
-MULTILIB_MATCHES  = mcpu?ARC600=mcpu?arc600
-MULTILIB_MATCHES += mcpu?ARC600=mARC600
-MULTILIB_MATCHES += mcpu?ARC600=mA6
-MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
-MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
-MULTILIB_MATCHES += mcpu?ARC700=mA7
-MULTILIB_MATCHES += mcpu?ARC700=mARC700
-MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700
-MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem
-MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs
-MULTILIB_MATCHES += EL=mlittle-endian
-MULTILIB_MATCHES += EB=mbig-endian
-#
-# These don't make sense for the ARC700 default target:
-MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm*
-# And neither of the -mmul* options make sense without -mnorm:
-MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
-# Exclusions for ARC700
-MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16*
-# Exclusions for ARCv2EM
-MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16*
-# Exclusions for ARCv2HS
-MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm*
diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-arc-uClibc
deleted file mode 100644
index 11e81f1..0000000
--- a/gcc/config/arc/t-arc-uClibc
+++ /dev/null
@@ -1,20 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
new file mode 100644
index 0000000..5a36af6
--- /dev/null
+++ b/gcc/config/arc/t-multilib
@@ -0,0 +1,34 @@
+# Auto-generated Makefile Snip
+# Generated by    : ./gcc/config/arc/genmultilib.awk
+# Generated from  : ./gcc/config/arc/arc-cpu.def
+# Used by         : tmake_file from Makefile and genmultilib
+
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
+
+MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
+
+# Aliases:
+MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
+MULTILIB_MATCHES += mcpu?arc600=mARC600
+MULTILIB_MATCHES += mcpu?arc600=mA6
+MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601
+MULTILIB_MATCHES += mcpu?arc700=mA7
+MULTILIB_MATCHES += mcpu?arc700=mARC700
diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc
new file mode 100644
index 0000000..11e81f1
--- /dev/null
+++ b/gcc/config/arc/t-uClibc
@@ -0,0 +1,20 @@
+# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
+
+# Copyright (C) 2007-2016 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+
+# You should have received a copy of the GNU General Public License along
+# with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3f9c0a0..4399733 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13882,29 +13882,92 @@ values for @var{cpu} are
 @table @samp
 @opindex mA6
 @opindex mARC600
-@item ARC600
 @item arc600
 Compile for ARC600.  Aliases: @option{-mA6}, @option{-mARC600}.
 
-@item ARC601
 @item arc601
 @opindex mARC601
 Compile for ARC601.  Alias: @option{-mARC601}.
 
-@item ARC700
 @item arc700
 @opindex mA7
 @opindex mARC700
 Compile for ARC700.  Aliases: @option{-mA7}, @option{-mARC700}.
 This is the default when configured with @option{--with-cpu=arc700}@.
 
-@item ARCEM
 @item arcem
 Compile for ARC EM.
 
-@item ARCHS
 @item archs
 Compile for ARC HS.
+
+@item em
+@opindex em
+Compile for ARC EM cpu with no hardware extension.
+
+@item em4
+@opindex em4
+Compile for ARC EM4 cpu.
+
+@item em4_dmips
+@opindex em4_dmips
+Compile for ARC EM4 DMIPS cpu.
+
+@item em4_fpus
+@opindex em4_fpus
+Compile for ARC EM4 DMIPS cpu with single precision floating point
+extension.
+
+@item em4_fpuda
+@opindex em4_fpuda
+Compile for ARC EM4 DMIPS cpu with single precision floating point and
+double assists instructions.
+
+@item hs
+@opindex hs
+Compile for ARC HS cpu with no hardware extension, except the atomic
+instructions.
+
+@item hs34
+@opindex hs34
+Compile for ARC HS34 cpu.
+
+@item hs38
+@opindex hs38
+Compile for ARC HS38 cpu.
+
+@item hs38_linux
+@opindex hs38_linux
+Compile for ARC HS38 cpu with all hardware extensions on.
+
+@item arc600_norm
+@opindex arc600_norm
+Compile for ARC 600 cpu with norm instruction enabled.
+
+@item arc600_mul32x16
+@opindex arc600_mul32x16
+Compile for ARC 600 cpu with norm and mul32x16 instructions enabled.
+
+@item arc600_mul64
+@opindex arc600_mul64
+Compile for ARC 600 cpu with norm and mul64 instructions enabled.
+
+@item arc601_norm
+@opindex arc601_norm
+Compile for ARC 601 cpu with norm instruction enabled.
+
+@item arc601_mul32x16
+@opindex arc601_mul32x16
+Compile for ARC 601 cpu with norm and mul32x16 instructions enabled.
+
+@item arc601_mul64
+@opindex arc601_mul64
+Compile for ARC 601 cpu with norm and mul64 instructions enabled.
+
+@item nps400
+@opindex nps400
+Compile for ARC 700 on NPS400 chip.
+
 @end table
 
 @item -mdpfp
@@ -13931,7 +13994,8 @@ supported.  This is always enabled for @option{-mcpu=ARC700}.
 
 @item -mno-mpy
 @opindex mno-mpy
-Do not generate mpy instructions for ARC700.
+Do not generate mpy instructions for ARC700.  This instruction is
+deprecated.
 
 @item -mmul32x16
 @opindex mmul32x16
@@ -14138,12 +14202,14 @@ define preprocessor macro symbols.
 @item -mdsp-packa
 @opindex mdsp-packa
 Passed down to the assembler to enable the DSP Pack A extensions.
-Also sets the preprocessor symbol @code{__Xdsp_packa}.
+Also sets the preprocessor symbol @code{__Xdsp_packa}.  This option is
+deprecated.
 
 @item -mdvbf
 @opindex mdvbf
 Passed down to the assembler to enable the dual viterbi butterfly
-extension.  Also sets the preprocessor symbol @code{__Xdvbf}.
+extension.  Also sets the preprocessor symbol @code{__Xdvbf}.  This
+option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mlock
@@ -14155,19 +14221,19 @@ Conditional extension.  Also sets the preprocessor symbol
 @item -mmac-d16
 @opindex mmac-d16
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_d16}.
+@code{__Xxmac_d16}.  This option is deprecated.
 
 @item -mmac-24
 @opindex mmac-24
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_24}.
+@code{__Xxmac_24}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mrtsc
 @opindex mrtsc
 Passed down to the assembler to enable the 64-bit Time-Stamp Counter
 extension instruction.  Also sets the preprocessor symbol
-@code{__Xrtsc}.
+@code{__Xrtsc}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mswape
@@ -14180,7 +14246,7 @@ extension instruction.  Also sets the preprocessor symbol
 @opindex mtelephony
 Passed down to the assembler to enable dual and single operand
 instructions for telephony.  Also sets the preprocessor symbol
-@code{__Xtelephony}.
+@code{__Xtelephony}.  This option is deprecated.
 
 @item -mxy
 @opindex mxy
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-11-10 11:04           ` Claudiu Zissulescu
@ 2016-11-14 10:33             ` Andrew Burgess
  2016-11-14 10:37               ` Claudiu Zissulescu
  2016-11-15  9:37               ` Claudiu Zissulescu
  0 siblings, 2 replies; 18+ messages in thread
From: Andrew Burgess @ 2016-11-14 10:33 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-11-10 12:02:34 +0100]:

> Hi,
> 
> Please find the revised patch which includes the refurbishing of
> mmpy-option option, and a new comment on DEFAULT_arc_fpu_build
> define. As for the last suggestion, my proposal is to have a latter
> patch on the topic of .cpu, synced with a related binutils patch.

I don't understand this last point.

HEAD binutils supports '.cpu NPS400' and HEAD GCC also correctly emits
'.cpu NPS400' (when -mcpu=nps400 is passed).  After your change we no
longer correctly emit '.cpu NPS400'.

I don't understand what syncing is required with binutils?

Thanks,
Andrew




> 
> OK to apply?
> Claudiu
> 
> gcc/
> 2016-05-09  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc-arch.h: New file.
> 	* config/arc/arc-arches.def: Likewise.
> 	* config/arc/arc-cpus.def: Likewise.
> 	* config/arc/arc-options.def: Likewise.
> 	* config/arc/t-multilib: Likewise.
> 	* config/arc/genmultilib.awk: Likewise.
> 	* config/arc/genoptions.awk: Likewise.
> 	* config/arc/arc-tables.opt: Likewise.
> 	* config/arc/driver-arc.c: Likewise.
> 	* common/config/arc/arc-common.c (arc_handle_option): Trace
> 	toggled options.
> 	* config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra
> 	options; check for supported cpu against arc-cpus.def file.
> 	(arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define
> 	TARGET_CPU_BUILD macro; add driver-arc.o as an extra object.
> 	* config/arc/arc-c.def: Add emacs local variables.
> 	* config/arc/arc-opts.h (processor_type): Use arc-cpus.def file.
> 	(FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA)
> 	(FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL)
> 	(FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines.
> 	(DEFAULT_arc_fpu_build): Define.
> 	(DEFAULT_arc_mpy_option): Define.
> 	* config/arc/arc-protos.h (arc_init): Delete.
> 	* config/arc/arc.c (arc_cpu_name): New variable.
> 	(arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs)
> 	(arc_arc700, arc_arc600, arc_arc601): New variable.
> 	(arc_init): Add static; remove selection of default tune value,
> 	cleanup obsolete error messages.
> 	(arc_override_options): Make use of .def files for selecting the
> 	right cpu and option configurations.
> 	* config/arc/arc.h (stdbool.h): Include.
> 	(TARGET_CPU_DEFAULT): Define.
> 	(CPP_SPEC): Remove mcpu=NPS400 handling.
> 	(arc_cpu_to_as): Declare.
> 	(EXTRA_SPEC_FUNCTIONS): Define.
> 	(OPTION_DEFAULT_SPECS): Likewise.
> 	(ASM_DEFAULT): Remove.
> 	(ASM_SPEC): Use arc_cpu_to_as.
> 	(DRIVER_SELF_SPECS): Remove deprecated options.
> 	(arc_base_cpu):	Declare.
> 	(TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM)
> 	(TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_base_cpu
> 	variable.
> 	(MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT.
> 	* config/arc/arc.md (attr_cpu): Remove.
> 	* config/arc/arc.opt (mno-mpy): Deprecate.
> 	(mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM)
> 	(mcpu=ARCHS): Remove.
> 	(mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc):
> 	Deprecate.
> 	(mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove.
> 	(arc_fpu): Use new defines.
> 	(mpy-option): Change to use numeric or string like inputs.
> 	* config/arc/t-arc (driver-arc.o): New target.
> 	(arc-cpus, t-multilib, arc-tables.opt): Likewise.
> 	* config/arc/t-arc-newlib: Delete.
> 	* config/arc/t-arc-uClibc: Renamed to t-uClibc.
> 	* doc/invoke.texi (ARC): Update arc options.
> ---
>  gcc/common/config/arc/arc-common.c |  69 ++++---------
>  gcc/config.gcc                     |  47 +++++----
>  gcc/config/arc/arc-arch.h          | 120 ++++++++++++++++++++++
>  gcc/config/arc/arc-arches.def      |  56 ++++++++++
>  gcc/config/arc/arc-c.def           |   4 +
>  gcc/config/arc/arc-cpus.def        |  75 ++++++++++++++
>  gcc/config/arc/arc-options.def     | 109 ++++++++++++++++++++
>  gcc/config/arc/arc-opts.h          |  49 +++++++--
>  gcc/config/arc/arc-protos.h        |   1 -
>  gcc/config/arc/arc-tables.opt      |  90 ++++++++++++++++
>  gcc/config/arc/arc.c               | 176 +++++++++++++++++---------------
>  gcc/config/arc/arc.h               |  89 ++++++++--------
>  gcc/config/arc/arc.md              |   5 -
>  gcc/config/arc/arc.opt             | 169 +++++++++++++++---------------
>  gcc/config/arc/driver-arc.c        |  78 ++++++++++++++
>  gcc/config/arc/genmultilib.awk     | 203 +++++++++++++++++++++++++++++++++++++
>  gcc/config/arc/genoptions.awk      |  86 ++++++++++++++++
>  gcc/config/arc/t-arc               |  19 ++++
>  gcc/config/arc/t-arc-newlib        |  46 ---------
>  gcc/config/arc/t-arc-uClibc        |  20 ----
>  gcc/config/arc/t-multilib          |  34 +++++++
>  gcc/config/arc/t-uClibc            |  20 ++++
>  gcc/doc/invoke.texi                |  90 +++++++++++++---
>  23 files changed, 1277 insertions(+), 378 deletions(-)
>  create mode 100644 gcc/config/arc/arc-arch.h
>  create mode 100644 gcc/config/arc/arc-arches.def
>  create mode 100644 gcc/config/arc/arc-cpus.def
>  create mode 100644 gcc/config/arc/arc-options.def
>  create mode 100644 gcc/config/arc/arc-tables.opt
>  create mode 100644 gcc/config/arc/driver-arc.c
>  create mode 100644 gcc/config/arc/genmultilib.awk
>  create mode 100644 gcc/config/arc/genoptions.awk
>  delete mode 100644 gcc/config/arc/t-arc-newlib
>  delete mode 100644 gcc/config/arc/t-arc-uClibc
>  create mode 100644 gcc/config/arc/t-multilib
>  create mode 100644 gcc/config/arc/t-uClibc
> 
> diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
> index 5b687fb..1dbddae 100644
> --- a/gcc/common/config/arc/arc-common.c
> +++ b/gcc/common/config/arc/arc-common.c
> @@ -2,6 +2,7 @@
>     Copyright (C) 1994-2016 Free Software Foundation, Inc.
>     Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
>  		on behalf of Synopsys Inc.
> +		Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
>  
>  This file is part of GCC.
>  
> @@ -61,17 +62,19 @@ static const struct default_options arc_option_optimization_table[] =
>  
>  /*  Process options.  */
>  static bool
> -arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
> +arc_handle_option (struct gcc_options *opts,
> +		   struct gcc_options *opts_set ATTRIBUTE_UNUSED,
>  		   const struct cl_decoded_option *decoded,
>  		   location_t loc)
>  {
>    size_t code = decoded->opt_index;
>    int value = decoded->value;
>    const char *arg = decoded->arg;
> +  static int mcpu_seen = PROCESSOR_NONE;
> +  char *p;
>  
>    switch (code)
>      {
> -      static int mcpu_seen = PROCESSOR_NONE;
>      case OPT_mcpu_:
>        /* N.B., at this point arc_cpu has already been set to its new value by
>  	 our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless.  */
> @@ -79,71 +82,33 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
>        if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
>  	warning_at (loc, 0, "multiple -mcpu= options specified.");
>        mcpu_seen = value;
> -
> -      switch (value)
> -	{
> -	case PROCESSOR_NPS400:
> -	  if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) )
> -	    opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1;
> -	  /* Fall through */
> -	case PROCESSOR_ARC600:
> -	case PROCESSOR_ARC700:
> -	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
> -	    opts->x_target_flags |= MASK_BARREL_SHIFTER;
> -	  break;
> -	case PROCESSOR_ARC601:
> -	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
> -	    opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
> -	  break;
> -	case PROCESSOR_ARCHS:
> -	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
> -	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
> -	    opts->x_target_flags |= MASK_CODE_DENSITY;	  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
> -	    opts->x_target_flags |= MASK_NORM_SET;	  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
> -	    opts->x_target_flags |= MASK_SWAP_SET;	  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
> -	    opts->x_target_flags |= MASK_DIVREM;	  /* Default: on.  */
> -	  break;
> -
> -	case PROCESSOR_ARCEM:
> -	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
> -	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
> -	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
> -	    opts->x_target_flags &= ~MASK_CODE_DENSITY;	  /* Default: off.  */
> -	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
> -	    opts->x_target_flags &= ~MASK_NORM_SET;	  /* Default: off.  */
> -	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
> -	    opts->x_target_flags &= ~MASK_SWAP_SET;	  /* Default: off.  */
> -	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
> -	    opts->x_target_flags &= ~MASK_DIVREM;	  /* Default: off.  */
> -	  break;
> -	default:
> -	  gcc_unreachable ();
> -	}
>        break;
>  
>      case OPT_mmpy_option_:
> -      if (value < 0 || value > 9)
> -	error_at (loc, "bad value %qs for -mmpy-option switch", arg);
> +      if (opts->x_arc_mpy_option == 1)
> +	warning_at (loc, 0, "Unsupported value for mmpy-option");
> +      break;
> +
> +    default:
>        break;
>      }
>  
>    return true;
>  }
>  
> +#undef  TARGET_OPTION_INIT_STRUCT
>  #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
> +
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
>  #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
> -#define TARGET_HANDLE_OPTION arc_handle_option
>  
>  #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
>  
> -/* We default to ARC700, which has the barrel shifter enabled.  */
> -#define TARGET_DEFAULT_TARGET_FLAGS \
> -  (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
> +#undef  TARGET_DEFAULT_TARGET_FLAGS
> +#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET)
>  
> +#undef  TARGET_HANDLE_OPTION
> +#define TARGET_HANDLE_OPTION arc_handle_option
>  
>  #include "common/common-target-def.h"
>  
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index 8fd07c5..50dca89 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -318,6 +318,7 @@ arc*-*-*)
>  	cpu_type=arc
>  	c_target_objs="arc-c.o"
>  	cxx_target_objs="arc-c.o"
> +	extra_options="${extra_options} arc/arc-tables.opt"
>  	;;
>  arm*-*-*)
>  	cpu_type=arm
> @@ -991,13 +992,12 @@ alpha*-dec-*vms*)
>  	;;
>  arc*-*-elf*)
>  	extra_headers="arc-simd.h"
> -	tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
> -	tmake_file="arc/t-arc-newlib arc/t-arc"
> -	case x"${with_cpu}" in
> -	  xarc600|xarc601|xarc700)
> -		target_cpu_default="TARGET_CPU_$with_cpu"
> -		;;
> -	esac
> +	tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
> +	tmake_file="arc/t-multilib arc/t-arc"
> +	extra_gcc_objs="driver-arc.o"
> +	if test "x$with_cpu" != x; then
> +		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
> +	fi
>  	if test x${with_endian} = x; then
>  		case ${target} in
>  		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
> @@ -1014,15 +1014,14 @@ arc*-*-elf*)
>  	;;
>  arc*-*-linux-uclibc*)
>  	extra_headers="arc-simd.h"
> -	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
> -	tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc"
> +	tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
> +	tmake_file="${tmake_file} arc/t-uClibc arc/t-arc"
>  	tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0"
>  	tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1"
> -	case x"${with_cpu}" in
> -	  xarc600|xarc601|xarc700)
> -		target_cpu_default="TARGET_CPU_$with_cpu"
> -		;;
> -	esac
> +	extra_gcc_objs="driver-arc.o"
> +	if test "x$with_cpu" != x; then
> +		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
> +	fi
>  	if test x${with_endian} = x; then
>  		case ${target} in
>  		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
> @@ -3605,15 +3604,19 @@ case "${target}" in
>  		done
>  		;;
>  
> -	arc*-*-*) # was:	arc*-*-linux-uclibc)
> +	arc*-*-*)
>  		supported_defaults="cpu"
> -		case $with_cpu in
> -		  arc600|arc601|arc700)
> -			;;
> -		  *) echo "Unknown cpu type"
> -			exit 1
> -			;;
> -		esac
> +
> +		if [ x"$with_cpu" = x ] \
> +		    || grep "^ARC_CPU ($with_cpu," \
> +		       ${srcdir}/config/arc/arc-cpus.def \
> +		       > /dev/null; then
> +		 # Ok
> +		 true
> +		else
> +		 echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
> +		 exit 1
> +		fi
>  		;;
>  
>  	arm*-*-*)
> diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
> new file mode 100644
> index 0000000..7994543
> --- /dev/null
> +++ b/gcc/config/arc/arc-arch.h
> @@ -0,0 +1,120 @@
> +/* Definitions of types that are used to store ARC architecture and
> +   device information.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +   Contributed by Claudiu Zissulescu (claziss@synopsys.com)
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify
> +it under the terms of the GNU General Public License as published by
> +the Free Software Foundation; either version 3, or (at your option)
> +any later version.
> +
> +GCC is distributed in the hope that it will be useful,
> +but WITHOUT ANY WARRANTY; without even the implied warranty of
> +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +GNU General Public License for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3.  If not see
> +<http://www.gnu.org/licenses/>.  */
> +
> +#ifndef GCC_ARC_ARCH_H
> +#define GCC_ARC_ARCH_H
> +
> +#ifndef IN_LIBGCC2
> +/* Architecture selection types.  */
> +
> +enum cpu_flags
> +  {
> +#define ARC_OPT(NAME, CODE, MASK, DOC)	    NAME = CODE,
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE,
> +#include "arc-options.def"
> +#undef ARC_OPT
> +#undef ARC_OPTX
> +    FL_END
> +  };
> +
> +
> +/* ARC architecture variants.  */
> +
> +enum base_architecture
> +  {
> +    BASE_ARCH_NONE,
> +#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)  BASE_ARCH_##ARCH,
> +#include "arc-arches.def"
> +#undef ARC_ARCH
> +    BASE_ARCH_END
> +  };
> +
> +
> +/* Tune variants.  Needs to match the attr_tune enum.  */
> +
> +enum arc_tune_attr
> +  {
> +    ARC_TUNE_NONE,
> +    ARC_TUNE_ARC600,
> +    ARC_TUNE_ARC700_4_2_STD,
> +    ARC_TUNE_ARC700_4_2_XMAC
> +  };
> +
> +/* CPU specific properties.  */
> +
> +typedef struct
> +{
> +  /* CPU name.  */
> +  const char *const name;
> +
> +  /* Architecture class.  */
> +  enum base_architecture arch;
> +
> +  /* Specific flags.  */
> +  const unsigned long long flags;
> +
> +  /* Tune value.  */
> +  enum arc_tune_attr tune;
> +} arc_cpu_t;
> +
> +
> +/* Architecture specific propoerties.  */
> +
> +typedef struct
> +{
> +  /* Architecture name.  */
> +  const char *const name;
> +
> +  /* Architecture class.  */
> +  enum base_architecture arch;
> +
> +  /* All allowed flags for this architecture.  */
> +  const unsigned long long flags;
> +
> +  /* Default flags for this architecture.  It is a subset of
> +     FLAGS.  */
> +  const unsigned long long dflags;
> +} arc_arch_t;
> +
> +
> +
> +const arc_arch_t arc_arch_types[] =
> +  {
> +    {"none", BASE_ARCH_NONE, 0, 0},
> +#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)	\
> +    {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS},
> +#include "arc-arches.def"
> +#undef ARC_ARCH
> +    {NULL, BASE_ARCH_END, 0, 0}
> +  };
> +
> +const arc_cpu_t arc_cpu_types[] =
> +  {
> +    {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE},
> +#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
> +    {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE},
> +#include "arc-cpus.def"
> +#undef ARC_CPU
> +    {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE}
> +  };
> +
> +#endif
> +#endif /* GCC_ARC_ARCH_H */
> diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
> new file mode 100644
> index 0000000..f24babb
> --- /dev/null
> +++ b/gcc/config/arc/arc-arches.def
> @@ -0,0 +1,56 @@
> +/* ARC ARCH architectures.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* List of all known ARC base architectures.  These defines are used
> +   to check if command line given options are valid for a specific
> +   architecture, and to set default architecture options, if needed.
> +
> +   Before including this file, define a macro:
> +
> +   ARC_ARCH (NAME, ARCH, DEV_HW_FACILITIES, DEF_HW_FACILITIES)
> +
> +   where the arguments are the fields of arc_arch_t:
> +
> +   NAME			Architecture given name;
> +
> +   ARCH			Architecture class as in enum base_architecture;
> +
> +   DEV_HW_FACILITIES	All allowed architecture hardware facilities.
> +			These facilities are represented as compiler
> +			options, defined in arc_options.def file.
> +
> +   DEF_HW_FACILITIES	Default flags for this architecture.  It is a
> +			subset of DEV_HW_FACILITIES.  */
> +
> +ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
> +	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
> +	  | FL_SIMD | FL_FPUDA, 0)
> +ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
> +	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
> +	  | FL_FPUS | FL_FPUD,						\
> +	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
> +ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
> +	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
> +ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
> +	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
> +	  FL_BS | FL_NORM | FL_SWAP)
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
> index 065e973..4cfd7b6 100644
> --- a/gcc/config/arc/arc-c.def
> +++ b/gcc/config/arc/arc-c.def
> @@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__",     TARGET_EM)
>  ARC_C_DEF ("__HS__",     TARGET_HS)
>  ARC_C_DEF ("__Xnorm",    TARGET_NORM)
>  ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER)
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
> new file mode 100644
> index 0000000..0ceb734
> --- /dev/null
> +++ b/gcc/config/arc/arc-cpus.def
> @@ -0,0 +1,75 @@
> +/* ARC CPU architectures.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* List of various ARC CPU configurations.  If updated, cd to
> +   $(builddir)/gcc and run
> +
> +   $ make arc-cpus
> +
> +   This will regenerate / update the following source files:
> +
> +   -  $(srcdir)/config/arc/t-multilib
> +   -  $(srcdir)/config/arc/arc-tables.opt
> +
> +   After that, rebuild everything and check-in the new sources to the
> +   repo.  This file defines the accepted values for -mcpu=<CPU>
> +   option.
> +
> +   Before including this file, define a macro:
> +
> +   ARC_CPU (NAME, ARCH, FLAGS, TUNE)
> +
> +   where the arguments are the fields of arc_cpu_t:
> +
> +   NAME	  A given arbitrary name.
> +   ARCH	  Base architecture for the given CPU.
> +   FLAGS  Specific hardware flags that are enabled by this CPU configuration,
> +	  as defined in arc-options.def file, and allowed by arc-arches.def
> +	  file.  The specific hardware flags are enumerated without using
> +	  spaces between the '|' character and consequtive flags.
> +   TUNE	  Tune value for the given configuration, otherwise NONE.  */
> +
> +ARC_CPU (em,	    em, 0, NONE)
> +ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
> +ARC_CPU (em4,	    em, FL_CD, NONE)
> +ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
> +ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
> +ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
> +
> +ARC_CPU (hs,	     hs, 0, NONE)
> +ARC_CPU (archs,	     hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
> +ARC_CPU (hs34,	     hs, FL_MPYOPT_2, NONE)
> +ARC_CPU (hs38,	     hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE)
> +ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE)
> +
> +ARC_CPU (arc600,	  6xx, FL_BS, ARC600)
> +ARC_CPU (arc600_norm,	  6xx, FL_BS|FL_NORM, ARC600)
> +ARC_CPU (arc600_mul64,	  6xx, FL_BS|FL_NORM|FL_MUL64, ARC600)
> +ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600)
> +ARC_CPU (arc601,	  6xx, 0, ARC600)
> +ARC_CPU (arc601_norm,	  6xx, FL_NORM, ARC600)
> +ARC_CPU (arc601_mul64,	  6xx, FL_NORM|FL_MUL64, ARC600)
> +ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600)
> +
> +ARC_CPU (arc700, 700, 0, ARC700_4_2_STD)
> +ARC_CPU (nps400, 700, 0, ARC700_4_2_STD)
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
> new file mode 100644
> index 0000000..0f9d36c
> --- /dev/null
> +++ b/gcc/config/arc/arc-options.def
> @@ -0,0 +1,109 @@
> +/* ARC options.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published
> +   by the Free Software Foundation; either version 3, or (at your
> +   option) any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +/* List of all known ARC hardware modifier options (i.e., compiler
> +   options that are selecting a hardware facility).  There can be two
> +   types options: simple switches (e.g. code-density option can be
> +   on/off), or can accept multiple values (e.g., fpu options).
> +
> +   For any valid HW option, define a macro:
> +
> +   ARC_OPT (NAME, CODE, MASK, DOC)
> +
> +   where:
> +   NAME	  Name (identifier) of a particular hardware modifier option,
> +	  as in enum cpu_flags.
> +
> +   CODE	  64-bit mask used to encode NAME.
> +
> +   MASK	  Corresponding GCC's MASK_<option> macro.
> +
> +   DOC	  A string used when emitting compiler errors or warnings.
> +
> +   For a multi-value option, define a macro for a valid value:
> +
> +   ARC_OPTX (NAME, CODE, VAR, VAL, DOC)
> +
> +   where:
> +   NAME	  Name (identifier) of a particular hardware modifier
> +	  configuration.
> +
> +   CODE	  64-bit mask used to encode NAME.  It will be encoded in the
> +	  same variable like options given via ARC_OPT.
> +
> +   VAR	  Corresponding GCC's option variable.
> +
> +   VAL	  Value to be set in VAR.
> +
> +   DOC	  A string used when emitting compiler errors or warnings.
> +
> +   All multi-value options are defined using ARC_OPTX and ARC_OPT.
> +   ARC_OPT contains a mask with all valid values for the given
> +   option.  */
> +
> +ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
> +ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
> +ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
> +
> +ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
> +ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
> +ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
> +ARC_OPT (FL_SWAP,     (1ULL << 7), MASK_SWAP_SET,	   "swap")
> +ARC_OPT (FL_MUL64,    (1ULL << 8), MASK_MUL64_SET,	   "mul64")
> +ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16")
> +
> +ARC_OPT (FL_EA,	      (1ULL << 11), MASK_EA_SET,	   "extended arithmetics")
> +ARC_OPT (FL_SPFP,     (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX")
> +ARC_OPT (FL_DPFP,     (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX")
> +ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET,	   "argonaut")
> +ARC_OPT (FL_SIMD,     (1ULL << 15), MASK_SIMD_SET,	   "simd")
> +
> +ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w")
> +ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1")
> +ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2")
> +ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3")
> +ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4")
> +ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5")
> +ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy")
> +ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd")
> +ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw")
> +
> +ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option")
> +ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option")
> +
> +ARC_OPTX (FL_FPU_FPUS,	    (1ULL << 26), arc_fpu_build, FPU_FPUS,	"mfpu=fpus")
> +ARC_OPTX (FL_FPU_FPUS_DIV,  (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV,	"mfpu=fpus_div")
> +ARC_OPTX (FL_FPU_FPUS_FMA,  (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA,	"mfpu=fpus_fma")
> +ARC_OPTX (FL_FPU_FPUS_ALL,  (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL,	"mfpu=fpus_all")
> +ARC_OPTX (FL_FPU_FPUDA,	    (1ULL << 30), arc_fpu_build, FPU_FPUDA,	"mfpu=fpuda")
> +ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div")
> +ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma")
> +ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all")
> +ARC_OPTX (FL_FPU_FPUD,	    (1ULL << 34), arc_fpu_build, FPU_FPUD,	"mfpu=fpud")
> +ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV,	"mfpu=fpud_div")
> +ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA,	"mfpu=fpud_fma")
> +ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL,	"mfpu=fpud_all")
> +
> +ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
> +ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
> +ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
> +
> +/* Local Variables: */
> +/* mode: c */
> +/* End: */
> diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
> index cbd7898..e5bca84 100644
> --- a/gcc/config/arc/arc-opts.h
> +++ b/gcc/config/arc/arc-opts.h
> @@ -18,15 +18,16 @@
>     along with GCC; see the file COPYING3.  If not see
>     <http://www.gnu.org/licenses/>.  */
>  
> +#ifndef ARC_OPTS_H
> +#define ARC_OPTS_H
> +
>  enum processor_type
>  {
> -  PROCESSOR_NONE,
> -  PROCESSOR_ARC600,
> -  PROCESSOR_ARC601,
> -  PROCESSOR_ARC700,
> -  PROCESSOR_NPS400,
> -  PROCESSOR_ARCEM,
> -  PROCESSOR_ARCHS
> +  PROCESSOR_NONE = 0,
> +#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)  PROCESSOR_##NAME,
> +#include "arc-cpus.def"
> +#undef ARC_CPU
> +  PROCESSOR_generic
>  };
>  
>  /* Single precision floating point.  */
> @@ -48,3 +49,37 @@ enum processor_type
>  /* Double precision floating point assist operations.  */
>  #define FPX_DP    0x0100
>  
> +/* fpus option combi.  */
> +#define FPU_FPUS  (FPU_SP | FPU_SC)
> +/* fpud option combi.  */
> +#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
> +/* fpuda option combi.  */
> +#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
> +/* fpuda_div option combi.  */
> +#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
> +/* fpuda_fma option combi.  */
> +#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
> +/* fpuda_all option combi.  */
> +#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
> +/* fpus_div option combi.  */
> +#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
> +/* fpus_fma option combi.  */
> +#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
> +/* fpus_all option combi.  */
> +#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
> +/* fpud_div option combi.  */
> +#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
> +/* fpud_fma option combi.  */
> +#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
> +/* fpud_all option combi.  */
> +#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
> +
> +/* Default FPU option value needed to mark if the variable in question
> +   is changed by a command line option or not.  This is required when
> +   we set the cpu's specific configuration.  */
> +#define DEFAULT_arc_fpu_build 0x10000000
> +
> +/* Default MPY option value.  */
> +#define DEFAULT_arc_mpy_option -1
> +
> +#endif /* ARC_OPTS_H */
> diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
> index ad5d4d3..d1266b4 100644
> --- a/gcc/config/arc/arc-protos.h
> +++ b/gcc/config/arc/arc-protos.h
> @@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
>  #endif /* TREE_CODE */
>  
>  
> -extern void arc_init (void);
>  extern unsigned int arc_compute_frame_size (int);
>  extern bool arc_ccfsm_branch_deleted_p (void);
>  extern void arc_ccfsm_record_branch_deleted (void);
> diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
> new file mode 100644
> index 0000000..0e7c50c
> --- /dev/null
> +++ b/gcc/config/arc/arc-tables.opt
> @@ -0,0 +1,90 @@
> +; Auto-generated Makefile Snip
> +; Generated by    : ./gcc/config/arc/genoptions.awk
> +; Generated from  : ./gcc/config/arc/arc-cpu.def
> +;
> +; Copyright (C) 2016 Free Software Foundation, Inc.
> +;
> +; This file is part of GCC.
> +;
> +; GCC is free software; you can redistribute it and/or modify it under
> +; the terms of the GNU General Public License as published by the Free
> +; Software Foundation; either version 3, or (at your option) any later
> +; version.
> +;
> +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +; for more details.
> +;
> +; You should have received a copy of the GNU General Public License
> +; along with GCC; see the file COPYING3.  If not see
> +; <http://www.gnu.org/licenses/>.
> +
> +Enum
> +Name(processor_type) Type(enum processor_type)
> +Known ARC CPUs (for use with the -mcpu= option):
> +
> +EnumValue
> +Enum(processor_type) String(em) Value(PROCESSOR_em)
> +
> +EnumValue
> +Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
> +
> +EnumValue
> +Enum(processor_type) String(em4) Value(PROCESSOR_em4)
> +
> +EnumValue
> +Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips)
> +
> +EnumValue
> +Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
> +
> +EnumValue
> +Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
> +
> +EnumValue
> +Enum(processor_type) String(hs) Value(PROCESSOR_hs)
> +
> +EnumValue
> +Enum(processor_type) String(archs) Value(PROCESSOR_archs)
> +
> +EnumValue
> +Enum(processor_type) String(hs34) Value(PROCESSOR_hs34)
> +
> +EnumValue
> +Enum(processor_type) String(hs38) Value(PROCESSOR_hs38)
> +
> +EnumValue
> +Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux)
> +
> +EnumValue
> +Enum(processor_type) String(arc600) Value(PROCESSOR_arc600)
> +
> +EnumValue
> +Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm)
> +
> +EnumValue
> +Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64)
> +
> +EnumValue
> +Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16)
> +
> +EnumValue
> +Enum(processor_type) String(arc601) Value(PROCESSOR_arc601)
> +
> +EnumValue
> +Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm)
> +
> +EnumValue
> +Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64)
> +
> +EnumValue
> +Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16)
> +
> +EnumValue
> +Enum(processor_type) String(arc700) Value(PROCESSOR_arc700)
> +
> +EnumValue
> +Enum(processor_type) String(nps400) Value(PROCESSOR_nps400)
> +
> +
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 5e8d6b4..8810e91 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -64,7 +64,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "alias.h"
>  
>  /* Which cpu we're compiling for (ARC600, ARC601, ARC700).  */
> -static const char *arc_cpu_string = "";
> +static char arc_cpu_name[10] = "";
> +static const char *arc_cpu_string = arc_cpu_name;
>  
>  /* ??? Loads can handle any constant, stores can only handle small ones.  */
>  /* OTOH, LIMMs cost extra, so their usefulness is limited.  */
> @@ -241,6 +242,12 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
>  						enum by_pieces_operation op,
>  						bool);
>  
> +static const arc_cpu_t *arc_selected_cpu;
> +static const arc_arch_t *arc_selected_arch;
> +
> +/* Global var which sets the current compilation architecture.  */
> +enum base_architecture arc_base_cpu;
> +
>  /* Implements target hook vector_mode_supported_p.  */
>  
>  static bool
> @@ -668,47 +675,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
>  
>  /* Called by OVERRIDE_OPTIONS to initialize various things.  */
>  
> -void
> +static void
>  arc_init (void)
>  {
> -  enum attr_tune tune_dflt = TUNE_NONE;
> -
> -  switch (arc_cpu)
> -    {
> -    case PROCESSOR_ARC600:
> -      arc_cpu_string = "ARC600";
> -      tune_dflt = TUNE_ARC600;
> -      break;
> -
> -    case PROCESSOR_ARC601:
> -      arc_cpu_string = "ARC601";
> -      tune_dflt = TUNE_ARC600;
> -      break;
> -
> -    case PROCESSOR_ARC700:
> -      arc_cpu_string = "ARC700";
> -      tune_dflt = TUNE_ARC700_4_2_STD;
> -      break;
> -
> -    case PROCESSOR_NPS400:
> -      arc_cpu_string = "NPS400";
> -      tune_dflt = TUNE_ARC700_4_2_STD;
> -      break;
> -
> -    case PROCESSOR_ARCEM:
> -      arc_cpu_string = "EM";
> -      break;
> -
> -    case PROCESSOR_ARCHS:
> -      arc_cpu_string = "HS";
> -      break;
> -
> -    default:
> -      gcc_unreachable ();
> -    }
> -
> -  if (arc_tune == TUNE_NONE)
> -    arc_tune = tune_dflt;
>    /* Note: arc_multcost is only used in rtx_cost if speed is true.  */
>    if (arc_multcost < 0)
>      switch (arc_tune)
> @@ -739,18 +708,10 @@ arc_init (void)
>  	break;
>        }
>  
> -  /* Support mul64 generation only for ARC600.  */
> -  if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY))
> -      error ("-mmul64 not supported for ARC700 or ARCv2");
> -
>    /* MPY instructions valid only for ARC700 or ARCv2.  */
>    if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
>        error ("-mno-mpy supported only for ARC700 or ARCv2");
>  
> -  /* mul/mac instructions only for ARC600.  */
> -  if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY))
> -      error ("-mmul32x16 supported only for ARC600 or ARC601");
> -
>    if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
>        error ("-mno-dpfp-lrsr supported only with -mdpfp");
>  
> @@ -763,23 +724,11 @@ arc_init (void)
>    if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
>      error ("-mspfp_fast not available on ARC600 or ARC601");
>  
> -  /* FPX-3. No FPX extensions on pre-ARC600 cores.  */
> -  if ((TARGET_DPFP || TARGET_SPFP)
> -      && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
> -    error ("FPX extensions not available on pre-ARC600 cores");
> -
> -  /* FPX-4.  No FPX extensions mixed with FPU extensions for ARC HS
> -     cpus.  */
> -  if ((TARGET_DPFP || TARGET_SPFP)
> -      && TARGET_HARD_FLOAT
> -      && TARGET_HS)
> +  /* FPX-4.  No FPX extensions mixed with FPU extensions.  */
> +  if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
> +      && TARGET_HARD_FLOAT)
>      error ("No FPX/FPU mixing allowed");
>  
> -  /* Only selected multiplier configurations are available for HS.  */
> -  if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
> -		    || (arc_mpy_option == 1)))
> -    error ("This multiplier configuration is not available for HS cores");
> -
>    /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic.  */
>    if (flag_pic && TARGET_ARC600_FAMILY)
>      {
> @@ -789,26 +738,6 @@ arc_init (void)
>        flag_pic = 0;
>      }
>  
> -  if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS))
> -    error ("-matomic is only supported for ARC700 or ARC HS cores");
> -
> -  /* ll64 ops only available for HS.  */
> -  if (TARGET_LL64 && !TARGET_HS)
> -    error ("-mll64 is only supported for ARC HS cores");
> -
> -  /* FPU support only for V2.  */
> -  if (TARGET_HARD_FLOAT)
> -    {
> -      if (TARGET_EM
> -	  && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
> -	error ("FPU double precision options are available for ARC HS only");
> -      if (TARGET_HS && (arc_fpu_build & FPX_DP))
> -	error ("FPU double precision assist "
> -	       "options are not available for ARC HS");
> -      if (!TARGET_HS && !TARGET_EM)
> -	error ("FPU options are available for ARCv2 architecture only");
> -    }
> -
>    arc_init_reg_tables ();
>  
>    /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
> @@ -853,7 +782,86 @@ static void
>  arc_override_options (void)
>  {
>    if (arc_cpu == PROCESSOR_NONE)
> -    arc_cpu = PROCESSOR_ARC700;
> +    arc_cpu = TARGET_CPU_DEFAULT;
> +
> +  /* Set the default cpu options.  */
> +  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
> +  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
> +  arc_base_cpu = arc_selected_arch->arch;
> +
> +  /* Set the architectures.  */
> +  switch (arc_selected_arch->arch)
> +    {
> +    case BASE_ARCH_em:
> +      arc_cpu_string = "EM";
> +      break;
> +    case BASE_ARCH_hs:
> +      arc_cpu_string = "HS";
> +      break;
> +    case BASE_ARCH_700:
> +      arc_cpu_string = "ARC700";
> +      break;
> +    case BASE_ARCH_6xx:
> +      arc_cpu_string = "ARC600";
> +      break;
> +    default:
> +      gcc_unreachable ();
> +    }
> +
> +  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
> +     specific flags are set in arc-common.c.  The architecture forces
> +     the default hardware configurations in, regardless what command
> +     line options are saying.  The CPU optional hw options can be
> +     turned on or off.  */
> +#define ARC_OPT(NAME, CODE, MASK, DOC)			\
> +  do {							\
> +    if ((arc_selected_cpu->flags & CODE)		\
> +	&& ((target_flags_explicit & MASK) == 0))	\
> +      target_flags |= MASK;				\
> +    if (arc_selected_arch->dflags & CODE)		\
> +      target_flags |= MASK;				\
> +  } while (0);
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
> +  do {						\
> +    if ((arc_selected_cpu->flags & CODE)	\
> +	&& (VAR == DEFAULT_##VAR))		\
> +      VAR = VAL;				\
> +    if (arc_selected_arch->dflags & CODE)	\
> +      VAR = VAL;				\
> +  } while (0);
> +
> +#include "arc-options.def"
> +
> +#undef ARC_OPTX
> +#undef ARC_OPT
> +
> +  /* Check options against architecture options.  Throw an error if
> +     option is not allowed.  */
> +#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
> +  do {								\
> +    if ((VAR == VAL)						\
> +	&& (!(arc_selected_arch->flags & CODE)))		\
> +      {								\
> +	error ("%s is not available for %s architecture",	\
> +	       DOC, arc_selected_arch->name);			\
> +      }								\
> +  } while (0);
> +#define ARC_OPT(NAME, CODE, MASK, DOC)				\
> +  do {								\
> +    if ((target_flags & MASK)					\
> +	&& (!(arc_selected_arch->flags & CODE)))		\
> +      error ("%s is not available for %s architecture",		\
> +	     DOC, arc_selected_arch->name);			\
> +  } while (0);
> +
> +#include "arc-options.def"
> +
> +#undef ARC_OPTX
> +#undef ARC_OPT
> +
> +  /* Set Tune option.  */
> +  if (arc_tune == TUNE_NONE)
> +    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
>  
>    if (arc_size_opt_level == 3)
>      optimize_size = 1;
> diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
> index c02e1cd..0f97afc 100644
> --- a/gcc/config/arc/arc.h
> +++ b/gcc/config/arc/arc.h
> @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_ARC_H
>  #define GCC_ARC_H
>  
> +#include <stdbool.h>
> +
>  /* Things to do:
>  
>     - incscc, decscc?
> @@ -39,6 +41,10 @@ along with GCC; see the file COPYING3.  If not see
>  #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
>  #define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
>  
> +#ifndef TARGET_CPU_DEFAULT
> +#define TARGET_CPU_DEFAULT	PROCESSOR_arc700
> +#endif
> +
>  /* Check if this symbol has a long_call attribute in its declaration */
>  #define SYMBOL_REF_LONG_CALL_P(X)	\
>  	((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
> @@ -74,9 +80,11 @@ along with GCC; see the file COPYING3.  If not see
>        GNU_USER_TARGET_OS_CPP_BUILTINS (); \
>      } \
>    while (0)
> -#endif
>  
> -/* Match the macros used in the assembler.  */
> +#endif /* DEFAULT_LIBC == LIBC_UCLIBC */
> +
> +/* Macros enabled by specific command line option.  FIXME: to be
> +   deprecatd.  */
>  #define CPP_SPEC "\
>  %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \
>  %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \
> @@ -85,34 +93,22 @@ along with GCC; see the file COPYING3.  If not see
>  %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \
>  %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \
>  %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \
> -%{mcpu=NPS400:-D__NPS400__} \
> -%{mcpu=nps400:-D__NPS400__} \
> -"
> +%{mcpu=nps400:-D__NPS400__}"
>  
>  #define CC1_SPEC "\
>  %{EB:%{EL:%emay not use both -EB and -EL}} \
>  %{EB:-mbig-endian} %{EL:-mlittle-endian} \
>  "
> +extern const char *arc_cpu_to_as (int argc, const char **argv);
> +
> +#define EXTRA_SPEC_FUNCTIONS			\
> +  { "cpu_to_as", arc_cpu_to_as },
> +
> +#define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "			\
> +  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
>  
> -#define ASM_DEFAULT "-mARC700 -mEA"
> -
> -#define ASM_SPEC  "\
> -%{mbig-endian|EB:-EB} %{EL} \
> -%{mcpu=ARC600:-mARC600} \
> -%{mcpu=ARC601:-mARC601} \
> -%{mcpu=ARC700:-mARC700} \
> -%{mcpu=ARC700:-mEA} \
> -%{!mcpu=*:" ASM_DEFAULT "} \
> -%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \
> -%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \
> -%{msimd} \
> -%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \
> -%{mcpu=ARC700|!mcpu=*:%{mlock}} \
> -%{mcpu=ARC700|!mcpu=*:%{mswape}} \
> -%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \
> -%{mcpu=ARCHS:-mHS} \
> -%{mcpu=ARCEM:-mEM} \
> -%{matomic:-mlock}"
> +#define OPTION_DEFAULT_SPECS						\
> +  {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
>  
>  #if DEFAULT_LIBC == LIBC_UCLIBC
>  /* Note that the default is to link against dynamic libraries, if they are
> @@ -196,17 +192,11 @@ along with GCC; see the file COPYING3.  If not see
>  #define TARGET_MMEDIUM_CALLS_DEFAULT 0
>  #endif
>  
> -#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \
> -  "%{mARC600|mA6: -mcpu=ARC600 %<mARC600 %<mA6}" \
> -  "%{mARC601: -mcpu=ARC601 %<mARC601}" \
> -  "%{mARC700|mA7: -mcpu=ARC700 %<mARC700 %<mA7}" \
> -  "%{mbarrel_shifte*: -mbarrel-shifte%* %<mbarrel_shifte*}" \
> -  "%{mEA: -mea %<mEA}" \
> -  "%{mspfp_*: -mspfp-%* %<mspfp_*}" \
> -  "%{mdpfp_*: -mdpfp-%* %<mdpfp_*}" \
> -  "%{mdsp_pack*: -mdsp-pack%* %<mdsp_pack*}" \
> -  "%{mmac_*: -mmac-%* %<mmac_*}" \
> -  "%{multcost=*: -mmultcost=%* %<multcost=*}"
> +#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS		   \
> +  "%{mARC600|mA6: -mcpu=arc600 %<mARC600 %<mA6 %<mARC600}"	   \
> +  "%{mARC601: -mcpu=arc601 %<mARC601}"				   \
> +  "%{mARC700|mA7: -mcpu=arc700 %<mARC700 %<mA7}"		   \
> +  "%{mEA: -mea %<mEA}"
>  
>  /* Run-time compilation parameters selecting different hardware subsets.  */
>  
> @@ -252,20 +242,21 @@ along with GCC; see the file COPYING3.  If not see
>     use conditional execution?  */
>  #define TARGET_AT_DBR_CONDEXEC  (!TARGET_ARC700 && !TARGET_V2)
>  
> -#define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
> -#define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
> -#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700	\
> -		       || arc_cpu == PROCESSOR_NPS400)
> -#define TARGET_EM     (arc_cpu == PROCESSOR_ARCEM)
> -#define TARGET_HS     (arc_cpu == PROCESSOR_ARCHS)
> -#define TARGET_V2							\
> -  ((arc_cpu == PROCESSOR_ARCHS) || (arc_cpu == PROCESSOR_ARCEM))
> -
> -/* Recast the cpu class to be the cpu attribute.  */
> -#define arc_cpu_attr ((enum attr_cpu)arc_cpu)
> -
> -#ifndef MULTILIB_DEFAULTS
> -#define MULTILIB_DEFAULTS { "mARC700" }
> +extern enum base_architecture arc_base_cpu;
> +
> +#define TARGET_ARC600 ((arc_base_cpu == BASE_ARCH_6xx)	\
> +		       && (TARGET_BARREL_SHIFTER))
> +#define TARGET_ARC601 ((arc_base_cpu == BASE_ARCH_6xx)	\
> +		       && (!TARGET_BARREL_SHIFTER))
> +#define TARGET_ARC700 (arc_base_cpu == BASE_ARCH_700)
> +#define TARGET_EM (arc_base_cpu == BASE_ARCH_em)
> +#define TARGET_HS (arc_base_cpu == BASE_ARCH_hs)
> +#define TARGET_V2 (TARGET_EM || TARGET_HS)
> +
> +#ifdef ARC_MULTILIB_CPU_DEFAULT
> +# ifndef MULTILIB_DEFAULTS
> +#  define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT }
> +# endif
>  #endif
>  
>  #ifndef UNALIGNED_ACCESS_DEFAULT
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index 715da31..6f757b6 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -231,11 +231,6 @@
>  	 (eq_attr "is_CALL" "yes") (const_string "yes")]
>  	(const_string "no")))
>  
> -
> -;; Attribute describing the processor
> -(define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
> -  (const (symbol_ref "arc_cpu_attr")))
> -
>  ;; true for compact instructions (those with _s suffix)
>  ;; "maybe" means compact unless we conditionalize the insn.
>  (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
> diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
> index 4caf366..5685100 100644
> --- a/gcc/config/arc/arc.opt
> +++ b/gcc/config/arc/arc.opt
> @@ -54,8 +54,74 @@ Target Report
>  Same as -mA7.
>  
>  mmpy-option=
> -Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
> --mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
> +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)
> @@ -100,7 +166,7 @@ Target Report Mask(MUL64_SET)
>  Generate mul64 and mulu64 instructions.
>  
>  mno-mpy
> -Target Report Mask(NOMPY_SET)
> +Target Report Mask(NOMPY_SET) Warn(%qs is deprecated)
>  Do not generate mpy instructions for ARC700.
>  
>  mea
> @@ -167,45 +233,6 @@ mcpu=
>  Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
>  -mcpu=CPU	Compile code for ARC variant CPU.
>  
> -Enum
> -Name(processor_type) Type(enum processor_type)
> -
> -EnumValue
> -Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
> -
> -EnumValue
> -Enum(processor_type) String(arc600) Value(PROCESSOR_ARC600)
> -
> -EnumValue
> -Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
> -
> -EnumValue
> -Enum(processor_type) String(arc601) Value(PROCESSOR_ARC601)
> -
> -EnumValue
> -Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
> -
> -EnumValue
> -Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700)
> -
> -EnumValue
> -Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400)
> -
> -EnumValue
> -Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400)
> -
> -EnumValue
> -Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM)
> -
> -EnumValue
> -Enum(processor_type) String(arcem) Value(PROCESSOR_ARCEM)
> -
> -EnumValue
> -Enum(processor_type) String(ARCHS) Value(PROCESSOR_ARCHS)
> -
> -EnumValue
> -Enum(processor_type) String(archs) Value(PROCESSOR_ARCHS)
> -
>  msize-level=
>  Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
>  size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os.
> @@ -308,25 +335,25 @@ Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
>  ; Flags used by the assembler, but for which we define preprocessor
>  ; macro symbols as well.
>  mcrc
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable variable polynomial CRC extension.
>  
>  mdsp-packa
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable DSP 3.1 Pack A extensions.
>  
>  mdvbf
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable dual viterbi butterfly extension.
>  
>  mmac-d16
> -Target Report Undocumented
> +Target Report Undocumented Warn(%qs is deprecated)
>  
>  mmac-24
> -Target Report Undocumented
> +Target Report Undocumented Warn(%qs is deprecated)
>  
>  mtelephony
> -Target Report RejectNegative
> +Target Report RejectNegative Warn(%qs is deprecated)
>  Enable Dual and Single Operand Instructions for Telephony.
>  
>  mxy
> @@ -343,7 +370,7 @@ Target Report
>  Enable swap byte ordering extension instruction.
>  
>  mrtsc
> -Target Report
> +Target Report Warn(%qs is deprecated)
>  Enable 64-bit Time-Stamp Counter extension instruction.
>  
>  EB
> @@ -394,24 +421,6 @@ Target
>  multcost=
>  Target RejectNegative Joined
>  
> -; Unfortunately, listing the full option name gives us clashes
> -; with OPT_opt_name being claimed for both opt_name and opt-name,
> -; so we leave out the last character or more.
> -mbarrel_shifte
> -Target Joined
> -
> -mspfp_
> -Target Joined
> -
> -mdpfp_
> -Target Joined
> -
> -mdsp_pack
> -Target Joined
> -
> -mmac_
> -Target Joined
> -
>  matomic
>  Target Report Mask(ATOMIC)
>  Enable atomic instructions.
> @@ -421,47 +430,47 @@ Target Report Mask(LL64)
>  Enable double load/store instructions for ARC HS.
>  
>  mfpu=
> -Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
> +Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(DEFAULT_arc_fpu_build)
>  Specify the name of the target floating point configuration.
>  
>  Enum
>  Name(arc_fpu) Type(int)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
> +Enum(arc_fpu) String(fpus) Value(FPU_FPUS)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
> +Enum(arc_fpu) String(fpud) Value(FPU_FPUD)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
> +Enum(arc_fpu) String(fpuda) Value(FPU_FPUDA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
> +Enum(arc_fpu) String(fpuda_div) Value(FPU_FPUDA_DIV)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
> +Enum(arc_fpu) String(fpuda_fma) Value(FPU_FPUDA_FMA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
> +Enum(arc_fpu) String(fpuda_all) Value(FPU_FPUDA_ALL)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
> +Enum(arc_fpu) String(fpus_div) Value(FPU_FPUS_DIV)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
> +Enum(arc_fpu) String(fpud_div) Value(FPU_FPUD_DIV)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
> +Enum(arc_fpu) String(fpus_fma) Value(FPU_FPUS_FMA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
> +Enum(arc_fpu) String(fpud_fma) Value(FPU_FPUD_FMA)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
> +Enum(arc_fpu) String(fpus_all) Value(FPU_FPUS_ALL)
>  
>  EnumValue
> -Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
> +Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL)
>  
>  mtp-regno=
>  Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25)
> diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
> new file mode 100644
> index 0000000..6117968
> --- /dev/null
> +++ b/gcc/config/arc/driver-arc.c
> @@ -0,0 +1,78 @@
> +/* Subroutines for the gcc driver.
> +   Copyright (C) 2016 Free Software Foundation, Inc.
> +   Contributed by Claudiu Zissulescu <claziss@synopsys.com>
> +
> +   This file is part of GCC.
> +
> +   GCC is free software; you can redistribute it and/or modify it
> +   under the terms of the GNU General Public License as published by
> +   the Free Software Foundation; either version 3, or (at your option)
> +   any later version.
> +
> +   GCC is distributed in the hope that it will be useful, but WITHOUT
> +   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> +   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> +   License for more details.
> +
> +   You should have received a copy of the GNU General Public License
> +   along with GCC; see the file COPYING3.  If not see
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "tm.h"
> +
> +/* Returns command line parameters to pass to as.  */
> +
> +const char*
> +arc_cpu_to_as (int argc, const char **argv)
> +{
> +  const char *name = NULL;
> +  const arc_cpu_t *arc_selected_cpu;
> +
> +  /* No argument, check what is the default cpu.  */
> +  if (argc == 0)
> +    {
> +      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
> +    }
> +  else
> +    {
> +      name = argv[0];
> +      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
> +	   arc_selected_cpu++)
> +	{
> +	  if (strcmp (arc_selected_cpu->name, name) == 0)
> +	    break;
> +	}
> +    }
> +
> +  switch (arc_selected_cpu->arch)
> +    {
> +    case BASE_ARCH_em:
> +      if (arc_selected_cpu->flags & FL_CD)
> +	name = "-mcode-density";
> +      else
> +	name = "";
> +      if (arc_selected_cpu->flags & FL_FPUDA)
> +	name = concat ("-mfpuda ", name, NULL);
> +      if (arc_selected_cpu->flags & FL_SPFP)
> +	name = concat ("-mspfp ", name, NULL);
> +      if (arc_selected_cpu->flags & FL_DPFP)
> +	name = concat ("-mdpfp ", name, NULL);
> +      return concat ("-mcpu=arcem ", name, NULL);
> +    case BASE_ARCH_hs:
> +      return "-mcpu=archs";
> +    case BASE_ARCH_700:
> +      return "-mcpu=arc700 -mEA";
> +    case BASE_ARCH_6xx:
> +      if (arc_selected_cpu->flags & FL_MUL64)
> +	return "-mcpu=arc600 -mmul64 -mnorm";
> +      if (arc_selected_cpu->flags & FL_MUL32x16)
> +	return "-mcpu=arc600 -mdsp-packa -mnorm";
> +      return "-mcpu=arc600 -mnorm";
> +    default:
> +      gcc_unreachable ();
> +    }
> +  return NULL;
> +}
> diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
> new file mode 100644
> index 0000000..5934f4f
> --- /dev/null
> +++ b/gcc/config/arc/genmultilib.awk
> @@ -0,0 +1,203 @@
> +# Copyright (C) 2016 Free Software Foundation, Inc.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 3, or (at your option) any later
> +# version.
> +#
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +# for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +##################################################################
> +#
> +# This file is using AVR's genmultilib.awk idea.
> +# Transform CPU Information from arc-cpu.def to a
> +# Representation that is understood by GCC's multilib Machinery.
> +#
> +# The Script works as a Filter from STDIN to STDOUT.
> +#
> +# FORMAT = "Makefile": Generate Makefile Snipet that sets some
> +#                      MULTILIB_* Variables as needed.
> +#
> +##################################################################
> +
> +BEGIN {
> +  FS ="[(, \t)]+"
> +  comment = 1
> +  n_cores = 0
> +  n_reuse = 0
> +}
> +
> +##################################################################
> +# Add some Comments to the generated Files and copy-paste
> +# Copyright Notice from above.
> +##################################################################
> +/^#/ {
> +  if (!comment)
> +    next
> +  else if (comment == 1)
> +    {
> +      if (FORMAT == "Makefile")
> +	{
> +	  print "# Auto-generated Makefile Snip"
> +	  print "# Generated by    : ./gcc/config/arc/genmultilib.awk"
> +	  print "# Generated from  : ./gcc/config/arc/arc-cpu.def"
> +	  print "# Used by         : tmake_file from Makefile and genmultilib"
> +	  print ""
> +	}
> +    }
> +
> +  comment = 2;
> +
> +  print
> +}
> +
> +/^$/ {
> +  # The first empty line stops copy-pasting the GPL comments
> +  # from this file to the generated file.
> +
> +  comment = 0
> +}
> +
> +
> +/^ARC_CPU/ {
> +  name = $2
> +  #  gsub ("\"", "", name)
> +
> +  if ($4 != "0")
> +    {
> +      arch = $3
> +      if (arch == "6xx")
> +	arch = 601
> +
> +      n = split ($4, cpu_flg, "|")
> +
> +      line = "mcpu." arch
> +      for (i = 1; i <= n; i++)
> +	{
> +	  if (cpu_flg[i] == "FL_MPYOPT_0")
> +	    line = line "/mmpy-option.0"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_1")
> +	    line = line "/mmpy-option.1"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_2")
> +	    line = line "/mmpy-option.2"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_3")
> +	    line = line "/mmpy-option.3"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_4")
> +	    line = line "/mmpy-option.4"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_5")
> +	    line = line "/mmpy-option.5"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_6")
> +	    line = line "/mmpy-option.6"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_7")
> +	    line = line "/mmpy-option.7"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_8")
> +	    line = line "/mmpy-option.8"
> +	  else if (cpu_flg[i] == "FL_MPYOPT_9")
> +	    line = line "/mmpy-option.9"
> +	  else if (cpu_flg[i] == "FL_CD")
> +	    line = line "/mcode-density"
> +	  else if (cpu_flg[i] == "FL_BS")
> +	    line = line "/mbarrel-shifter"
> +	  else if (cpu_flg[i] == "FL_DIVREM")
> +	    line = line "/mdiv-rem"
> +	  else if (cpu_flg[i] == "FL_NORM" \
> +		   || cpu_flg[i] == "FL_SWAP")
> +	    line = line "/mnorm"
> +	  else if (cpu_flg[i] == "FL_FPU_FPUS")
> +	    line = line "/mfpu.fpus"
> +	  else if (cpu_flg[i] == "FL_FPU_FPUDA")
> +	    line = line "/mfpu.fpuda"
> +	  else if (cpu_flg[i] == "FL_FPU_FPUD_ALL")
> +	    line = line "/mfpu.fpud_all"
> +	  else if (cpu_flg[i] == "FL_LL64")
> +	    line = line "/mll64"
> +	  else if (cpu_flg[i] == "FL_MUL64")
> +	    line = line "/mmul64"
> +	  else if (cpu_flg[i] == "FL_MUL32x16")
> +	    line = line "/mmul32x16"
> +	  else if (cpu_flg[i] == "FL_FPX_QUARK")
> +	    line = line "/quark"
> +	  else if (cpu_flg[i] == "FL_SPFP")
> +	    line = line "/spfp"
> +	  else if (cpu_flg[i] == "FL_DPFP")
> +	    line = line "/dpfp"
> +	  else
> +	    {
> +	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
> +	      exit 1
> +	    }
> +	}
> +      line = "mcpu." name "=" line
> +      reuse[n_reuse] = line
> +      n_reuse++
> +    }
> +
> +  core = name
> +  cores[n_cores] = core
> +  n_cores++
> +}
> +
> +##################################################################
> +#
> +# We gathered all the Information, now build/output the following:
> +#
> +#    awk Variable         target Variable          FORMAT
> +#  -----------------------------------------------------------
> +#    m_options     <->    MULTILIB_OPTIONS         Makefile
> +#    m_dirnames    <->    MULTILIB_DIRNAMES           "
> +#
> +##################################################################
> +
> +END {
> +  m_options    = "\nMULTILIB_OPTIONS = "
> +  m_dirnames   = "\nMULTILIB_DIRNAMES ="
> +  m_reuse      = "\nMULTILIB_REUSE ="
> +
> +  sep = ""
> +  for (c = 0; c < n_cores; c++)
> +    {
> +      m_options  = m_options sep "mcpu=" cores[c]
> +      m_dirnames = m_dirnames " " cores[c]
> +      sep = "/"
> +    }
> +
> +  sep = ""
> +  for (c = 0; c < n_reuse; c++)
> +    {
> +      m_reuse = m_reuse sep reuse[c]
> +      sep = "\nMULTILIB_REUSE +="
> +    }
> +  ############################################################
> +  # Output that Stuff
> +  ############################################################
> +
> +  if (FORMAT == "Makefile")
> +    {
> +      # Intended Target: ./gcc/config/arc/t-multilib
> +
> +      print m_options
> +      print m_dirnames
> +
> +      ############################################################
> +      # Legacy Aliases
> +      ############################################################
> +
> +      print ""
> +      print "# Aliases:"
> +      print "MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600"
> +      print "MULTILIB_MATCHES += mcpu?arc600=mARC600"
> +      print "MULTILIB_MATCHES += mcpu?arc600=mA6"
> +      print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601"
> +      print "MULTILIB_MATCHES += mcpu?arc700=mA7"
> +      print "MULTILIB_MATCHES += mcpu?arc700=mARC700"
> +    }
> +}
> diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk
> new file mode 100644
> index 0000000..24a93eb
> --- /dev/null
> +++ b/gcc/config/arc/genoptions.awk
> @@ -0,0 +1,86 @@
> +# Copyright (C) 2016 Free Software Foundation, Inc.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 3, or (at your option) any later
> +# version.
> +#
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +# for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +##################################################################
> +#
> +# This file is using AVR's genmultilib.awk idea.
> +#
> +##################################################################
> +
> +BEGIN {
> +  FS ="[(, \t)]+"
> +  comment = 1
> +  n_cores = 0
> +}
> +
> +##################################################################
> +# Add some Comments to the generated Files and copy-paste
> +# Copyright Notice from above.
> +##################################################################
> +/^#/ {
> +  if (!comment)
> +    next
> +  else if (comment == 1)
> +    {
> +      if (FORMAT == "Makefile")
> +	{
> +	  print "; Auto-generated Makefile Snip"
> +	  print "; Generated by    : ./gcc/config/arc/genoptions.awk"
> +	  print "; Generated from  : ./gcc/config/arc/arc-cpu.def"
> +	  print ";"
> +	}
> +    }
> +
> +  comment = 2;
> +
> +  gsub ("^#", ";", $0)
> +  print
> +}
> +
> +/^$/ {
> +    # The first empty line stops copy-pasting the GPL comments
> +    # from this file to the generated file.
> +    comment = 0
> +}
> +
> +/^ARC_CPU/ {
> +  name = $2
> +  cores[n_cores] = name;
> +  n_cores++
> +}
> +
> +END {
> +  m_option = ""
> +  for (c = 0; c < n_cores; c++)
> +    {
> +      m_options = m_options "EnumValue\nEnum(processor_type) String(" \
> +	cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n"
> +    }
> +
> +  ############################################################
> +  # Output that Stuff
> +  ############################################################
> +
> +  if (FORMAT == "Makefile")
> +    {
> +	print "\nEnum"
> +	print "Name(processor_type) Type(enum processor_type)"
> +	print "Known ARC CPUs (for use with the -mcpu= option):\n"
> +	print m_options
> +    }
> +}
> diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
> index 4252e73..bdb1328 100644
> --- a/gcc/config/arc/t-arc
> +++ b/gcc/config/arc/t-arc
> @@ -19,11 +19,30 @@
>  
>  TM_H += $(srcdir)/config/arc/arc-c.def
>  
> +driver-arc.o: $(srcdir)/config/arc/driver-arc.c \
> +  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
> +	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
> +
>  arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \
>  $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
>  	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
>  		$(srcdir)/config/arc/arc-c.c
>  
> +#Run `arc-cpus` if you changed something in arc-cpus.def
> +
> +.PHONY: arc-cpus
> +
> +arc-cpus: $(srcdir)/config/arc/t-multilib \
> +	$(srcdir)/config/arc/arc-tables.opt
> +
> +$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk 	\
> +				 $(srcdir)/config/arc/arc-cpus.def
> +	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
> +
> +$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \
> +				 $(srcdir)/config/arc/arc-cpus.def
> +	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
> +
>  # Local Variables:
>  # mode: Makefile
>  # End:
> diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib
> deleted file mode 100644
> index c49a3fcc..0000000
> --- a/gcc/config/arc/t-arc-newlib
> +++ /dev/null
> @@ -1,46 +0,0 @@
> -# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
> -
> -# Copyright (C) 2007-2016 Free Software Foundation, Inc.
> -
> -# This file is part of GCC.
> -
> -# GCC is free software; you can redistribute it and/or modify it under the
> -# terms of the GNU General Public License as published by the Free Software
> -# Foundation; either version 3, or (at your option) any later version.
> -
> -# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
> -# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
> -# details.
> -
> -# You should have received a copy of the GNU General Public License along
> -# with GCC; see the file COPYING3.  If not see
> -# <http://www.gnu.org/licenses/>.
> -
> -MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm
> -MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm
> -#
> -# Aliases:
> -MULTILIB_MATCHES  = mcpu?ARC600=mcpu?arc600
> -MULTILIB_MATCHES += mcpu?ARC600=mARC600
> -MULTILIB_MATCHES += mcpu?ARC600=mA6
> -MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
> -MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
> -MULTILIB_MATCHES += mcpu?ARC700=mA7
> -MULTILIB_MATCHES += mcpu?ARC700=mARC700
> -MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700
> -MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem
> -MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs
> -MULTILIB_MATCHES += EL=mlittle-endian
> -MULTILIB_MATCHES += EB=mbig-endian
> -#
> -# These don't make sense for the ARC700 default target:
> -MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm*
> -# And neither of the -mmul* options make sense without -mnorm:
> -MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
> -# Exclusions for ARC700
> -MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16*
> -# Exclusions for ARCv2EM
> -MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16*
> -# Exclusions for ARCv2HS
> -MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm*
> diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-arc-uClibc
> deleted file mode 100644
> index 11e81f1..0000000
> --- a/gcc/config/arc/t-arc-uClibc
> +++ /dev/null
> @@ -1,20 +0,0 @@
> -# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
> -
> -# Copyright (C) 2007-2016 Free Software Foundation, Inc.
> -
> -# This file is part of GCC.
> -
> -# GCC is free software; you can redistribute it and/or modify it under the
> -# terms of the GNU General Public License as published by the Free Software
> -# Foundation; either version 3, or (at your option) any later version.
> -
> -# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
> -# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
> -# details.
> -
> -# You should have received a copy of the GNU General Public License along
> -# with GCC; see the file COPYING3.  If not see
> -# <http://www.gnu.org/licenses/>.
> -
> -MULTILIB_EXTRA_OPTS = mno-sdata
> diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
> new file mode 100644
> index 0000000..5a36af6
> --- /dev/null
> +++ b/gcc/config/arc/t-multilib
> @@ -0,0 +1,34 @@
> +# Auto-generated Makefile Snip
> +# Generated by    : ./gcc/config/arc/genmultilib.awk
> +# Generated from  : ./gcc/config/arc/arc-cpu.def
> +# Used by         : tmake_file from Makefile and genmultilib
> +
> +# Copyright (C) 2016 Free Software Foundation, Inc.
> +#
> +# This file is part of GCC.
> +#
> +# GCC is free software; you can redistribute it and/or modify it under
> +# the terms of the GNU General Public License as published by the Free
> +# Software Foundation; either version 3, or (at your option) any later
> +# version.
> +#
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
> +# for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
> +
> +MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
> +
> +# Aliases:
> +MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
> +MULTILIB_MATCHES += mcpu?arc600=mARC600
> +MULTILIB_MATCHES += mcpu?arc600=mA6
> +MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601
> +MULTILIB_MATCHES += mcpu?arc700=mA7
> +MULTILIB_MATCHES += mcpu?arc700=mARC700
> diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc
> new file mode 100644
> index 0000000..11e81f1
> --- /dev/null
> +++ b/gcc/config/arc/t-uClibc
> @@ -0,0 +1,20 @@
> +# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
> +
> +# Copyright (C) 2007-2016 Free Software Foundation, Inc.
> +
> +# This file is part of GCC.
> +
> +# GCC is free software; you can redistribute it and/or modify it under the
> +# terms of the GNU General Public License as published by the Free Software
> +# Foundation; either version 3, or (at your option) any later version.
> +
> +# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
> +# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
> +# details.
> +
> +# You should have received a copy of the GNU General Public License along
> +# with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +MULTILIB_EXTRA_OPTS = mno-sdata
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index 3f9c0a0..4399733 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -13882,29 +13882,92 @@ values for @var{cpu} are
>  @table @samp
>  @opindex mA6
>  @opindex mARC600
> -@item ARC600
>  @item arc600
>  Compile for ARC600.  Aliases: @option{-mA6}, @option{-mARC600}.
>  
> -@item ARC601
>  @item arc601
>  @opindex mARC601
>  Compile for ARC601.  Alias: @option{-mARC601}.
>  
> -@item ARC700
>  @item arc700
>  @opindex mA7
>  @opindex mARC700
>  Compile for ARC700.  Aliases: @option{-mA7}, @option{-mARC700}.
>  This is the default when configured with @option{--with-cpu=arc700}@.
>  
> -@item ARCEM
>  @item arcem
>  Compile for ARC EM.
>  
> -@item ARCHS
>  @item archs
>  Compile for ARC HS.
> +
> +@item em
> +@opindex em
> +Compile for ARC EM cpu with no hardware extension.
> +
> +@item em4
> +@opindex em4
> +Compile for ARC EM4 cpu.
> +
> +@item em4_dmips
> +@opindex em4_dmips
> +Compile for ARC EM4 DMIPS cpu.
> +
> +@item em4_fpus
> +@opindex em4_fpus
> +Compile for ARC EM4 DMIPS cpu with single precision floating point
> +extension.
> +
> +@item em4_fpuda
> +@opindex em4_fpuda
> +Compile for ARC EM4 DMIPS cpu with single precision floating point and
> +double assists instructions.
> +
> +@item hs
> +@opindex hs
> +Compile for ARC HS cpu with no hardware extension, except the atomic
> +instructions.
> +
> +@item hs34
> +@opindex hs34
> +Compile for ARC HS34 cpu.
> +
> +@item hs38
> +@opindex hs38
> +Compile for ARC HS38 cpu.
> +
> +@item hs38_linux
> +@opindex hs38_linux
> +Compile for ARC HS38 cpu with all hardware extensions on.
> +
> +@item arc600_norm
> +@opindex arc600_norm
> +Compile for ARC 600 cpu with norm instruction enabled.
> +
> +@item arc600_mul32x16
> +@opindex arc600_mul32x16
> +Compile for ARC 600 cpu with norm and mul32x16 instructions enabled.
> +
> +@item arc600_mul64
> +@opindex arc600_mul64
> +Compile for ARC 600 cpu with norm and mul64 instructions enabled.
> +
> +@item arc601_norm
> +@opindex arc601_norm
> +Compile for ARC 601 cpu with norm instruction enabled.
> +
> +@item arc601_mul32x16
> +@opindex arc601_mul32x16
> +Compile for ARC 601 cpu with norm and mul32x16 instructions enabled.
> +
> +@item arc601_mul64
> +@opindex arc601_mul64
> +Compile for ARC 601 cpu with norm and mul64 instructions enabled.
> +
> +@item nps400
> +@opindex nps400
> +Compile for ARC 700 on NPS400 chip.
> +
>  @end table
>  
>  @item -mdpfp
> @@ -13931,7 +13994,8 @@ supported.  This is always enabled for @option{-mcpu=ARC700}.
>  
>  @item -mno-mpy
>  @opindex mno-mpy
> -Do not generate mpy instructions for ARC700.
> +Do not generate mpy instructions for ARC700.  This instruction is
> +deprecated.
>  
>  @item -mmul32x16
>  @opindex mmul32x16
> @@ -14138,12 +14202,14 @@ define preprocessor macro symbols.
>  @item -mdsp-packa
>  @opindex mdsp-packa
>  Passed down to the assembler to enable the DSP Pack A extensions.
> -Also sets the preprocessor symbol @code{__Xdsp_packa}.
> +Also sets the preprocessor symbol @code{__Xdsp_packa}.  This option is
> +deprecated.
>  
>  @item -mdvbf
>  @opindex mdvbf
>  Passed down to the assembler to enable the dual viterbi butterfly
> -extension.  Also sets the preprocessor symbol @code{__Xdvbf}.
> +extension.  Also sets the preprocessor symbol @code{__Xdvbf}.  This
> +option is deprecated.
>  
>  @c ARC700 4.10 extension instruction
>  @item -mlock
> @@ -14155,19 +14221,19 @@ Conditional extension.  Also sets the preprocessor symbol
>  @item -mmac-d16
>  @opindex mmac-d16
>  Passed down to the assembler.  Also sets the preprocessor symbol
> -@code{__Xxmac_d16}.
> +@code{__Xxmac_d16}.  This option is deprecated.
>  
>  @item -mmac-24
>  @opindex mmac-24
>  Passed down to the assembler.  Also sets the preprocessor symbol
> -@code{__Xxmac_24}.
> +@code{__Xxmac_24}.  This option is deprecated.
>  
>  @c ARC700 4.10 extension instruction
>  @item -mrtsc
>  @opindex mrtsc
>  Passed down to the assembler to enable the 64-bit Time-Stamp Counter
>  extension instruction.  Also sets the preprocessor symbol
> -@code{__Xrtsc}.
> +@code{__Xrtsc}.  This option is deprecated.
>  
>  @c ARC700 4.10 extension instruction
>  @item -mswape
> @@ -14180,7 +14246,7 @@ extension instruction.  Also sets the preprocessor symbol
>  @opindex mtelephony
>  Passed down to the assembler to enable dual and single operand
>  instructions for telephony.  Also sets the preprocessor symbol
> -@code{__Xtelephony}.
> +@code{__Xtelephony}.  This option is deprecated.
>  
>  @item -mxy
>  @opindex mxy
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-11-14 10:33             ` Andrew Burgess
@ 2016-11-14 10:37               ` Claudiu Zissulescu
  2016-11-15  9:37               ` Claudiu Zissulescu
  1 sibling, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-11-14 10:37 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, Francois.Bedard

> HEAD binutils supports '.cpu NPS400' and HEAD GCC also correctly emits
> '.cpu NPS400' (when -mcpu=nps400 is passed).  After your change we no
> longer correctly emit '.cpu NPS400'.
> 

Sorry for this miss-understanding. Updating the patch to emit .cpu NSPS400.

Thanks,
Claudiu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] [ARC] New option handling, refurbish multilib support.
  2016-11-14 10:33             ` Andrew Burgess
  2016-11-14 10:37               ` Claudiu Zissulescu
@ 2016-11-15  9:37               ` Claudiu Zissulescu
       [not found]                 ` <20161115123637.GB5975@embecosm.com>
  1 sibling, 1 reply; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-11-15  9:37 UTC (permalink / raw)
  To: gcc-patches; +Cc: Claudiu.Zissulescu

Please find attached the revised patch as requested.

Ok to apply?
Claudiu

gcc/
2016-05-09  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc-arch.h: New file.
	* config/arc/arc-arches.def: Likewise.
	* config/arc/arc-cpus.def: Likewise.
	* config/arc/arc-options.def: Likewise.
	* config/arc/t-multilib: Likewise.
	* config/arc/genmultilib.awk: Likewise.
	* config/arc/genoptions.awk: Likewise.
	* config/arc/arc-tables.opt: Likewise.
	* config/arc/driver-arc.c: Likewise.
	* testsuite/gcc.target/arc/nps400-cpu-flag.c: Likewise.
	* common/config/arc/arc-common.c (arc_handle_option): Trace
	toggled options.
	* config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra
	options; check for supported cpu against arc-cpus.def file.
	(arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define
	TARGET_CPU_BUILD macro; add driver-arc.o as an extra object.
	* config/arc/arc-c.def: Add emacs local variables.
	* config/arc/arc-opts.h (processor_type): Use arc-cpus.def file.
	(FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA)
	(FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL)
	(FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines.
	(DEFAULT_arc_fpu_build): Define.
	(DEFAULT_arc_mpy_option): Define.
	* config/arc/arc-protos.h (arc_init): Delete.
	* config/arc/arc.c (arc_cpu_name): New variable.
	(arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs)
	(arc_arc700, arc_arc600, arc_arc601): New variable.
	(arc_init): Add static; remove selection of default tune value,
	cleanup obsolete error messages.
	(arc_override_options): Make use of .def files for selecting the
	right cpu and option configurations.
	* config/arc/arc.h (stdbool.h): Include.
	(TARGET_CPU_DEFAULT): Define.
	(CPP_SPEC): Remove mcpu=NPS400 handling.
	(arc_cpu_to_as): Declare.
	(EXTRA_SPEC_FUNCTIONS): Define.
	(OPTION_DEFAULT_SPECS): Likewise.
	(ASM_DEFAULT): Remove.
	(ASM_SPEC): Use arc_cpu_to_as.
	(DRIVER_SELF_SPECS): Remove deprecated options.
	(arc_base_cpu):	Declare.
	(TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM)
	(TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_base_cpu
	variable.
	(MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT.
	* config/arc/arc.md (attr_cpu): Remove.
	* config/arc/arc.opt (mno-mpy): Deprecate.
	(mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM)
	(mcpu=ARCHS): Remove.
	(mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc):
	Deprecate.
	(mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove.
	(arc_fpu): Use new defines.
	(mpy-option): Change to use numeric or string like inputs.
	* config/arc/t-arc (driver-arc.o): New target.
	(arc-cpus, t-multilib, arc-tables.opt): Likewise.
	* config/arc/t-arc-newlib: Delete.
	* config/arc/t-arc-uClibc: Renamed to t-uClibc.
	* doc/invoke.texi (ARC): Update arc options.
---
 gcc/common/config/arc/arc-common.c             |  69 +++------
 gcc/config.gcc                                 |  47 +++---
 gcc/config/arc/arc-arch.h                      | 123 +++++++++++++++
 gcc/config/arc/arc-arches.def                  |  56 +++++++
 gcc/config/arc/arc-c.def                       |   4 +
 gcc/config/arc/arc-cpus.def                    |  75 +++++++++
 gcc/config/arc/arc-options.def                 | 109 +++++++++++++
 gcc/config/arc/arc-opts.h                      |  49 +++++-
 gcc/config/arc/arc-protos.h                    |   1 -
 gcc/config/arc/arc-tables.opt                  |  90 +++++++++++
 gcc/config/arc/arc.c                           | 179 ++++++++++++----------
 gcc/config/arc/arc.h                           |  89 +++++------
 gcc/config/arc/arc.md                          |   5 -
 gcc/config/arc/arc.opt                         | 169 ++++++++++----------
 gcc/config/arc/driver-arc.c                    |  81 ++++++++++
 gcc/config/arc/genmultilib.awk                 | 203 +++++++++++++++++++++++++
 gcc/config/arc/genoptions.awk                  |  86 +++++++++++
 gcc/config/arc/t-arc                           |  19 +++
 gcc/config/arc/t-arc-newlib                    |  46 ------
 gcc/config/arc/t-arc-uClibc                    |  20 ---
 gcc/config/arc/t-multilib                      |  34 +++++
 gcc/config/arc/t-uClibc                        |  20 +++
 gcc/doc/invoke.texi                            |  90 +++++++++--
 gcc/testsuite/gcc.target/arc/nps400-cpu-flag.c |   4 +
 24 files changed, 1290 insertions(+), 378 deletions(-)
 create mode 100644 gcc/config/arc/arc-arch.h
 create mode 100644 gcc/config/arc/arc-arches.def
 create mode 100644 gcc/config/arc/arc-cpus.def
 create mode 100644 gcc/config/arc/arc-options.def
 create mode 100644 gcc/config/arc/arc-tables.opt
 create mode 100644 gcc/config/arc/driver-arc.c
 create mode 100644 gcc/config/arc/genmultilib.awk
 create mode 100644 gcc/config/arc/genoptions.awk
 delete mode 100644 gcc/config/arc/t-arc-newlib
 delete mode 100644 gcc/config/arc/t-arc-uClibc
 create mode 100644 gcc/config/arc/t-multilib
 create mode 100644 gcc/config/arc/t-uClibc
 create mode 100644 gcc/testsuite/gcc.target/arc/nps400-cpu-flag.c

diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index 5b687fb..1dbddae 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -2,6 +2,7 @@
    Copyright (C) 1994-2016 Free Software Foundation, Inc.
    Contributor: Joern Rennecke <joern.rennecke@embecosm.com>
 		on behalf of Synopsys Inc.
+		Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>
 
 This file is part of GCC.
 
@@ -61,17 +62,19 @@ static const struct default_options arc_option_optimization_table[] =
 
 /*  Process options.  */
 static bool
-arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
+arc_handle_option (struct gcc_options *opts,
+		   struct gcc_options *opts_set ATTRIBUTE_UNUSED,
 		   const struct cl_decoded_option *decoded,
 		   location_t loc)
 {
   size_t code = decoded->opt_index;
   int value = decoded->value;
   const char *arg = decoded->arg;
+  static int mcpu_seen = PROCESSOR_NONE;
+  char *p;
 
   switch (code)
     {
-      static int mcpu_seen = PROCESSOR_NONE;
     case OPT_mcpu_:
       /* N.B., at this point arc_cpu has already been set to its new value by
 	 our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless.  */
@@ -79,71 +82,33 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
       if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value)
 	warning_at (loc, 0, "multiple -mcpu= options specified.");
       mcpu_seen = value;
-
-      switch (value)
-	{
-	case PROCESSOR_NPS400:
-	  if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) )
-	    opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1;
-	  /* Fall through */
-	case PROCESSOR_ARC600:
-	case PROCESSOR_ARC700:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARC601:
-	  if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) )
-	    opts->x_target_flags &= ~MASK_BARREL_SHIFTER;
-	  break;
-	case PROCESSOR_ARCHS:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags |= MASK_CODE_DENSITY;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags |= MASK_NORM_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags |= MASK_SWAP_SET;	  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags |= MASK_DIVREM;	  /* Default: on.  */
-	  break;
-
-	case PROCESSOR_ARCEM:
-	  if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER))
-	    opts->x_target_flags |= MASK_BARREL_SHIFTER;  /* Default: on.  */
-	  if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY))
-	    opts->x_target_flags &= ~MASK_CODE_DENSITY;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_NORM_SET))
-	    opts->x_target_flags &= ~MASK_NORM_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_SWAP_SET))
-	    opts->x_target_flags &= ~MASK_SWAP_SET;	  /* Default: off.  */
-	  if ( !(opts_set->x_target_flags & MASK_DIVREM))
-	    opts->x_target_flags &= ~MASK_DIVREM;	  /* Default: off.  */
-	  break;
-	default:
-	  gcc_unreachable ();
-	}
       break;
 
     case OPT_mmpy_option_:
-      if (value < 0 || value > 9)
-	error_at (loc, "bad value %qs for -mmpy-option switch", arg);
+      if (opts->x_arc_mpy_option == 1)
+	warning_at (loc, 0, "Unsupported value for mmpy-option");
+      break;
+
+    default:
       break;
     }
 
   return true;
 }
 
+#undef  TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct
+
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
 #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table
-#define TARGET_HANDLE_OPTION arc_handle_option
 
 #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET)
 
-/* We default to ARC700, which has the barrel shifter enabled.  */
-#define TARGET_DEFAULT_TARGET_FLAGS \
-  (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA)
+#undef  TARGET_DEFAULT_TARGET_FLAGS
+#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET)
 
+#undef  TARGET_HANDLE_OPTION
+#define TARGET_HANDLE_OPTION arc_handle_option
 
 #include "common/common-target-def.h"
 
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 8fd07c5..50dca89 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -318,6 +318,7 @@ arc*-*-*)
 	cpu_type=arc
 	c_target_objs="arc-c.o"
 	cxx_target_objs="arc-c.o"
+	extra_options="${extra_options} arc/arc-tables.opt"
 	;;
 arm*-*-*)
 	cpu_type=arm
@@ -991,13 +992,12 @@ alpha*-dec-*vms*)
 	;;
 arc*-*-elf*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
-	tmake_file="arc/t-arc-newlib arc/t-arc"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}"
+	tmake_file="arc/t-multilib arc/t-arc"
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -1014,15 +1014,14 @@ arc*-*-elf*)
 	;;
 arc*-*-linux-uclibc*)
 	extra_headers="arc-simd.h"
-	tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
-	tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc"
+	tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}"
+	tmake_file="${tmake_file} arc/t-uClibc arc/t-arc"
 	tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0"
 	tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1"
-	case x"${with_cpu}" in
-	  xarc600|xarc601|xarc700)
-		target_cpu_default="TARGET_CPU_$with_cpu"
-		;;
-	esac
+	extra_gcc_objs="driver-arc.o"
+	if test "x$with_cpu" != x; then
+		tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu"
+	fi
 	if test x${with_endian} = x; then
 		case ${target} in
 		arc*be-*-* | arc*eb-*-*)	with_endian=big ;;
@@ -3605,15 +3604,19 @@ case "${target}" in
 		done
 		;;
 
-	arc*-*-*) # was:	arc*-*-linux-uclibc)
+	arc*-*-*)
 		supported_defaults="cpu"
-		case $with_cpu in
-		  arc600|arc601|arc700)
-			;;
-		  *) echo "Unknown cpu type"
-			exit 1
-			;;
-		esac
+
+		if [ x"$with_cpu" = x ] \
+		    || grep "^ARC_CPU ($with_cpu," \
+		       ${srcdir}/config/arc/arc-cpus.def \
+		       > /dev/null; then
+		 # Ok
+		 true
+		else
+		 echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2
+		 exit 1
+		fi
 		;;
 
 	arm*-*-*)
diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
new file mode 100644
index 0000000..bfd3f23
--- /dev/null
+++ b/gcc/config/arc/arc-arch.h
@@ -0,0 +1,123 @@
+/* Definitions of types that are used to store ARC architecture and
+   device information.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu (claziss@synopsys.com)
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ARC_ARCH_H
+#define GCC_ARC_ARCH_H
+
+#ifndef IN_LIBGCC2
+/* Architecture selection types.  */
+
+enum cpu_flags
+  {
+#define ARC_OPT(NAME, CODE, MASK, DOC)	    NAME = CODE,
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE,
+#include "arc-options.def"
+#undef ARC_OPT
+#undef ARC_OPTX
+    FL_END
+  };
+
+
+/* ARC architecture variants.  */
+
+enum base_architecture
+  {
+    BASE_ARCH_NONE,
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)  BASE_ARCH_##ARCH,
+#include "arc-arches.def"
+#undef ARC_ARCH
+    BASE_ARCH_END
+  };
+
+
+/* Tune variants.  Needs to match the attr_tune enum.  */
+
+enum arc_tune_attr
+  {
+    ARC_TUNE_NONE,
+    ARC_TUNE_ARC600,
+    ARC_TUNE_ARC700_4_2_STD,
+    ARC_TUNE_ARC700_4_2_XMAC
+  };
+
+/* CPU specific properties.  */
+
+typedef struct
+{
+  /* CPU name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* Specific processor type.  */
+  enum processor_type processor;
+
+  /* Specific flags.  */
+  const unsigned long long flags;
+
+  /* Tune value.  */
+  enum arc_tune_attr tune;
+} arc_cpu_t;
+
+
+/* Architecture specific propoerties.  */
+
+typedef struct
+{
+  /* Architecture name.  */
+  const char *const name;
+
+  /* Architecture class.  */
+  enum base_architecture arch;
+
+  /* All allowed flags for this architecture.  */
+  const unsigned long long flags;
+
+  /* Default flags for this architecture.  It is a subset of
+     FLAGS.  */
+  const unsigned long long dflags;
+} arc_arch_t;
+
+
+
+const arc_arch_t arc_arch_types[] =
+  {
+    {"none", BASE_ARCH_NONE, 0, 0},
+#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS)	\
+    {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS},
+#include "arc-arches.def"
+#undef ARC_ARCH
+    {NULL, BASE_ARCH_END, 0, 0}
+  };
+
+const arc_cpu_t arc_cpu_types[] =
+  {
+    {"none", BASE_ARCH_NONE, PROCESSOR_NONE, 0, ARC_TUNE_NONE},
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)	\
+    {#NAME, BASE_ARCH_##ARCH, PROCESSOR_##NAME, FLAGS, ARC_TUNE_##TUNE},
+#include "arc-cpus.def"
+#undef ARC_CPU
+    {NULL, BASE_ARCH_END, PROCESSOR_NONE, 0, ARC_TUNE_NONE}
+  };
+
+#endif
+#endif /* GCC_ARC_ARCH_H */
diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def
new file mode 100644
index 0000000..f24babb
--- /dev/null
+++ b/gcc/config/arc/arc-arches.def
@@ -0,0 +1,56 @@
+/* ARC ARCH architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of all known ARC base architectures.  These defines are used
+   to check if command line given options are valid for a specific
+   architecture, and to set default architecture options, if needed.
+
+   Before including this file, define a macro:
+
+   ARC_ARCH (NAME, ARCH, DEV_HW_FACILITIES, DEF_HW_FACILITIES)
+
+   where the arguments are the fields of arc_arch_t:
+
+   NAME			Architecture given name;
+
+   ARCH			Architecture class as in enum base_architecture;
+
+   DEV_HW_FACILITIES	All allowed architecture hardware facilities.
+			These facilities are represented as compiler
+			options, defined in arc_options.def file.
+
+   DEF_HW_FACILITIES	Default flags for this architecture.  It is a
+			subset of DEV_HW_FACILITIES.  */
+
+ARC_ARCH ("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM	\
+	  | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP		\
+	  | FL_SIMD | FL_FPUDA, 0)
+ARC_ARCH ("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD	\
+	  | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP			\
+	  | FL_FPUS | FL_FPUD,						\
+	  FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP)
+ARC_ARCH ("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \
+	  | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0)
+ARC_ARCH ("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \
+	  | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP,		       \
+	  FL_BS | FL_NORM | FL_SWAP)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def
index 065e973..4cfd7b6 100644
--- a/gcc/config/arc/arc-c.def
+++ b/gcc/config/arc/arc-c.def
@@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__",     TARGET_EM)
 ARC_C_DEF ("__HS__",     TARGET_HS)
 ARC_C_DEF ("__Xnorm",    TARGET_NORM)
 ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def
new file mode 100644
index 0000000..0ceb734
--- /dev/null
+++ b/gcc/config/arc/arc-cpus.def
@@ -0,0 +1,75 @@
+/* ARC CPU architectures.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of various ARC CPU configurations.  If updated, cd to
+   $(builddir)/gcc and run
+
+   $ make arc-cpus
+
+   This will regenerate / update the following source files:
+
+   -  $(srcdir)/config/arc/t-multilib
+   -  $(srcdir)/config/arc/arc-tables.opt
+
+   After that, rebuild everything and check-in the new sources to the
+   repo.  This file defines the accepted values for -mcpu=<CPU>
+   option.
+
+   Before including this file, define a macro:
+
+   ARC_CPU (NAME, ARCH, FLAGS, TUNE)
+
+   where the arguments are the fields of arc_cpu_t:
+
+   NAME	  A given arbitrary name.
+   ARCH	  Base architecture for the given CPU.
+   FLAGS  Specific hardware flags that are enabled by this CPU configuration,
+	  as defined in arc-options.def file, and allowed by arc-arches.def
+	  file.  The specific hardware flags are enumerated without using
+	  spaces between the '|' character and consequtive flags.
+   TUNE	  Tune value for the given configuration, otherwise NONE.  */
+
+ARC_CPU (em,	    em, 0, NONE)
+ARC_CPU (arcem,	    em, FL_MPYOPT_2|FL_CD|FL_BS, NONE)
+ARC_CPU (em4,	    em, FL_CD, NONE)
+ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE)
+ARC_CPU (em4_fpus,  em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE)
+ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE)
+
+ARC_CPU (hs,	     hs, 0, NONE)
+ARC_CPU (archs,	     hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs34,	     hs, FL_MPYOPT_2, NONE)
+ARC_CPU (hs38,	     hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE)
+ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE)
+
+ARC_CPU (arc600,	  6xx, FL_BS, ARC600)
+ARC_CPU (arc600_norm,	  6xx, FL_BS|FL_NORM, ARC600)
+ARC_CPU (arc600_mul64,	  6xx, FL_BS|FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600)
+ARC_CPU (arc601,	  6xx, 0, ARC600)
+ARC_CPU (arc601_norm,	  6xx, FL_NORM, ARC600)
+ARC_CPU (arc601_mul64,	  6xx, FL_NORM|FL_MUL64, ARC600)
+ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600)
+
+ARC_CPU (arc700, 700, 0, ARC700_4_2_STD)
+ARC_CPU (nps400, 700, 0, ARC700_4_2_STD)
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def
new file mode 100644
index 0000000..0f9d36c
--- /dev/null
+++ b/gcc/config/arc/arc-options.def
@@ -0,0 +1,109 @@
+/* ARC options.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 3, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+/* List of all known ARC hardware modifier options (i.e., compiler
+   options that are selecting a hardware facility).  There can be two
+   types options: simple switches (e.g. code-density option can be
+   on/off), or can accept multiple values (e.g., fpu options).
+
+   For any valid HW option, define a macro:
+
+   ARC_OPT (NAME, CODE, MASK, DOC)
+
+   where:
+   NAME	  Name (identifier) of a particular hardware modifier option,
+	  as in enum cpu_flags.
+
+   CODE	  64-bit mask used to encode NAME.
+
+   MASK	  Corresponding GCC's MASK_<option> macro.
+
+   DOC	  A string used when emitting compiler errors or warnings.
+
+   For a multi-value option, define a macro for a valid value:
+
+   ARC_OPTX (NAME, CODE, VAR, VAL, DOC)
+
+   where:
+   NAME	  Name (identifier) of a particular hardware modifier
+	  configuration.
+
+   CODE	  64-bit mask used to encode NAME.  It will be encoded in the
+	  same variable like options given via ARC_OPT.
+
+   VAR	  Corresponding GCC's option variable.
+
+   VAL	  Value to be set in VAR.
+
+   DOC	  A string used when emitting compiler errors or warnings.
+
+   All multi-value options are defined using ARC_OPTX and ARC_OPT.
+   ARC_OPT contains a mask with all valid values for the given
+   option.  */
+
+ARC_OPT (FL_CD,	      (1ULL << 0), MASK_CODE_DENSITY,	   "code density")
+ARC_OPT (FL_DIVREM,   (1ULL << 1), MASK_DIVREM,		   "div/rem")
+ARC_OPT (FL_NORM,     (1ULL << 2), MASK_NORM_SET,	   "norm")
+
+ARC_OPT (FL_ATOMIC,   (1ULL << 4), MASK_ATOMIC,		   "atomic")
+ARC_OPT (FL_LL64,     (1ULL << 5), MASK_LL64,		   "double load/store")
+ARC_OPT (FL_BS,	      (1ULL << 6), MASK_BARREL_SHIFTER,	   "barrel shifter")
+ARC_OPT (FL_SWAP,     (1ULL << 7), MASK_SWAP_SET,	   "swap")
+ARC_OPT (FL_MUL64,    (1ULL << 8), MASK_MUL64_SET,	   "mul64")
+ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16")
+
+ARC_OPT (FL_EA,	      (1ULL << 11), MASK_EA_SET,	   "extended arithmetics")
+ARC_OPT (FL_SPFP,     (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX")
+ARC_OPT (FL_DPFP,     (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX")
+ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET,	   "argonaut")
+ARC_OPT (FL_SIMD,     (1ULL << 15), MASK_SIMD_SET,	   "simd")
+
+ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w")
+ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1")
+ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2")
+ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3")
+ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4")
+ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5")
+ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy")
+ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd")
+ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw")
+
+ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option")
+ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option")
+
+ARC_OPTX (FL_FPU_FPUS,	    (1ULL << 26), arc_fpu_build, FPU_FPUS,	"mfpu=fpus")
+ARC_OPTX (FL_FPU_FPUS_DIV,  (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV,	"mfpu=fpus_div")
+ARC_OPTX (FL_FPU_FPUS_FMA,  (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA,	"mfpu=fpus_fma")
+ARC_OPTX (FL_FPU_FPUS_ALL,  (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL,	"mfpu=fpus_all")
+ARC_OPTX (FL_FPU_FPUDA,	    (1ULL << 30), arc_fpu_build, FPU_FPUDA,	"mfpu=fpuda")
+ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div")
+ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma")
+ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all")
+ARC_OPTX (FL_FPU_FPUD,	    (1ULL << 34), arc_fpu_build, FPU_FPUD,	"mfpu=fpud")
+ARC_OPTX (FL_FPU_FPUD_DIV,  (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV,	"mfpu=fpud_div")
+ARC_OPTX (FL_FPU_FPUD_FMA,  (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA,	"mfpu=fpud_fma")
+ARC_OPTX (FL_FPU_FPUD_ALL,  (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL,	"mfpu=fpud_all")
+
+ARC_OPT (FL_FPUS,  (0xFULL << 26), 0, "single precission floating point")
+ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist")
+ARC_OPT (FL_FPUD,  (0xF0FULL << 26), 0, "double precission floating point")
+
+/* Local Variables: */
+/* mode: c */
+/* End: */
diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
index cbd7898..e5bca84 100644
--- a/gcc/config/arc/arc-opts.h
+++ b/gcc/config/arc/arc-opts.h
@@ -18,15 +18,16 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#ifndef ARC_OPTS_H
+#define ARC_OPTS_H
+
 enum processor_type
 {
-  PROCESSOR_NONE,
-  PROCESSOR_ARC600,
-  PROCESSOR_ARC601,
-  PROCESSOR_ARC700,
-  PROCESSOR_NPS400,
-  PROCESSOR_ARCEM,
-  PROCESSOR_ARCHS
+  PROCESSOR_NONE = 0,
+#define ARC_CPU(NAME, ARCH, FLAGS, TUNE)  PROCESSOR_##NAME,
+#include "arc-cpus.def"
+#undef ARC_CPU
+  PROCESSOR_generic
 };
 
 /* Single precision floating point.  */
@@ -48,3 +49,37 @@ enum processor_type
 /* Double precision floating point assist operations.  */
 #define FPX_DP    0x0100
 
+/* fpus option combi.  */
+#define FPU_FPUS  (FPU_SP | FPU_SC)
+/* fpud option combi.  */
+#define FPU_FPUD  (FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+/* fpuda option combi.  */
+#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP)
+/* fpuda_div option combi.  */
+#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+/* fpuda_fma option combi.  */
+#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+/* fpuda_all option combi.  */
+#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+/* fpus_div option combi.  */
+#define FPU_FPUS_DIV  (FPU_SP | FPU_SC | FPU_SD)
+/* fpus_fma option combi.  */
+#define FPU_FPUS_FMA  (FPU_SP | FPU_SC | FPU_SF)
+/* fpus_all option combi.  */
+#define FPU_FPUS_ALL  (FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+/* fpud_div option combi.  */
+#define FPU_FPUD_DIV  (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD)
+/* fpud_fma option combi.  */
+#define FPU_FPUD_FMA  (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF)
+/* fpud_all option combi.  */
+#define FPU_FPUD_ALL  (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+
+/* Default FPU option value needed to mark if the variable in question
+   is changed by a command line option or not.  This is required when
+   we set the cpu's specific configuration.  */
+#define DEFAULT_arc_fpu_build 0x10000000
+
+/* Default MPY option value.  */
+#define DEFAULT_arc_mpy_option -1
+
+#endif /* ARC_OPTS_H */
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index ad5d4d3..d1266b4 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *);
 #endif /* TREE_CODE */
 
 
-extern void arc_init (void);
 extern unsigned int arc_compute_frame_size (int);
 extern bool arc_ccfsm_branch_deleted_p (void);
 extern void arc_ccfsm_record_branch_deleted (void);
diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt
new file mode 100644
index 0000000..0e7c50c
--- /dev/null
+++ b/gcc/config/arc/arc-tables.opt
@@ -0,0 +1,90 @@
+; Auto-generated Makefile Snip
+; Generated by    : ./gcc/config/arc/genoptions.awk
+; Generated from  : ./gcc/config/arc/arc-cpu.def
+;
+; Copyright (C) 2016 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 3, or (at your option) any later
+; version.
+;
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING3.  If not see
+; <http://www.gnu.org/licenses/>.
+
+Enum
+Name(processor_type) Type(enum processor_type)
+Known ARC CPUs (for use with the -mcpu= option):
+
+EnumValue
+Enum(processor_type) String(em) Value(PROCESSOR_em)
+
+EnumValue
+Enum(processor_type) String(arcem) Value(PROCESSOR_arcem)
+
+EnumValue
+Enum(processor_type) String(em4) Value(PROCESSOR_em4)
+
+EnumValue
+Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips)
+
+EnumValue
+Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus)
+
+EnumValue
+Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda)
+
+EnumValue
+Enum(processor_type) String(hs) Value(PROCESSOR_hs)
+
+EnumValue
+Enum(processor_type) String(archs) Value(PROCESSOR_archs)
+
+EnumValue
+Enum(processor_type) String(hs34) Value(PROCESSOR_hs34)
+
+EnumValue
+Enum(processor_type) String(hs38) Value(PROCESSOR_hs38)
+
+EnumValue
+Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux)
+
+EnumValue
+Enum(processor_type) String(arc600) Value(PROCESSOR_arc600)
+
+EnumValue
+Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm)
+
+EnumValue
+Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64)
+
+EnumValue
+Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc601) Value(PROCESSOR_arc601)
+
+EnumValue
+Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm)
+
+EnumValue
+Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64)
+
+EnumValue
+Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16)
+
+EnumValue
+Enum(processor_type) String(arc700) Value(PROCESSOR_arc700)
+
+EnumValue
+Enum(processor_type) String(nps400) Value(PROCESSOR_nps400)
+
+
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 5e8d6b4..368ad00 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -64,7 +64,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "alias.h"
 
 /* Which cpu we're compiling for (ARC600, ARC601, ARC700).  */
-static const char *arc_cpu_string = "";
+static char arc_cpu_name[10] = "";
+static const char *arc_cpu_string = arc_cpu_name;
 
 /* ??? Loads can handle any constant, stores can only handle small ones.  */
 /* OTOH, LIMMs cost extra, so their usefulness is limited.  */
@@ -241,6 +242,12 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
 						enum by_pieces_operation op,
 						bool);
 
+static const arc_cpu_t *arc_selected_cpu;
+static const arc_arch_t *arc_selected_arch;
+
+/* Global var which sets the current compilation architecture.  */
+enum base_architecture arc_base_cpu;
+
 /* Implements target hook vector_mode_supported_p.  */
 
 static bool
@@ -668,47 +675,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
 
 /* Called by OVERRIDE_OPTIONS to initialize various things.  */
 
-void
+static void
 arc_init (void)
 {
-  enum attr_tune tune_dflt = TUNE_NONE;
-
-  switch (arc_cpu)
-    {
-    case PROCESSOR_ARC600:
-      arc_cpu_string = "ARC600";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC601:
-      arc_cpu_string = "ARC601";
-      tune_dflt = TUNE_ARC600;
-      break;
-
-    case PROCESSOR_ARC700:
-      arc_cpu_string = "ARC700";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_NPS400:
-      arc_cpu_string = "NPS400";
-      tune_dflt = TUNE_ARC700_4_2_STD;
-      break;
-
-    case PROCESSOR_ARCEM:
-      arc_cpu_string = "EM";
-      break;
-
-    case PROCESSOR_ARCHS:
-      arc_cpu_string = "HS";
-      break;
-
-    default:
-      gcc_unreachable ();
-    }
-
-  if (arc_tune == TUNE_NONE)
-    arc_tune = tune_dflt;
   /* Note: arc_multcost is only used in rtx_cost if speed is true.  */
   if (arc_multcost < 0)
     switch (arc_tune)
@@ -739,18 +708,10 @@ arc_init (void)
 	break;
       }
 
-  /* Support mul64 generation only for ARC600.  */
-  if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul64 not supported for ARC700 or ARCv2");
-
   /* MPY instructions valid only for ARC700 or ARCv2.  */
   if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
       error ("-mno-mpy supported only for ARC700 or ARCv2");
 
-  /* mul/mac instructions only for ARC600.  */
-  if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY))
-      error ("-mmul32x16 supported only for ARC600 or ARC601");
-
   if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
       error ("-mno-dpfp-lrsr supported only with -mdpfp");
 
@@ -763,23 +724,11 @@ arc_init (void)
   if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
     error ("-mspfp_fast not available on ARC600 or ARC601");
 
-  /* FPX-3. No FPX extensions on pre-ARC600 cores.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM))
-    error ("FPX extensions not available on pre-ARC600 cores");
-
-  /* FPX-4.  No FPX extensions mixed with FPU extensions for ARC HS
-     cpus.  */
-  if ((TARGET_DPFP || TARGET_SPFP)
-      && TARGET_HARD_FLOAT
-      && TARGET_HS)
+  /* FPX-4.  No FPX extensions mixed with FPU extensions.  */
+  if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
+      && TARGET_HARD_FLOAT)
     error ("No FPX/FPU mixing allowed");
 
-  /* Only selected multiplier configurations are available for HS.  */
-  if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7)
-		    || (arc_mpy_option == 1)))
-    error ("This multiplier configuration is not available for HS cores");
-
   /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic.  */
   if (flag_pic && TARGET_ARC600_FAMILY)
     {
@@ -789,26 +738,6 @@ arc_init (void)
       flag_pic = 0;
     }
 
-  if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS))
-    error ("-matomic is only supported for ARC700 or ARC HS cores");
-
-  /* ll64 ops only available for HS.  */
-  if (TARGET_LL64 && !TARGET_HS)
-    error ("-mll64 is only supported for ARC HS cores");
-
-  /* FPU support only for V2.  */
-  if (TARGET_HARD_FLOAT)
-    {
-      if (TARGET_EM
-	  && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP)))
-	error ("FPU double precision options are available for ARC HS only");
-      if (TARGET_HS && (arc_fpu_build & FPX_DP))
-	error ("FPU double precision assist "
-	       "options are not available for ARC HS");
-      if (!TARGET_HS && !TARGET_EM)
-	error ("FPU options are available for ARCv2 architecture only");
-    }
-
   arc_init_reg_tables ();
 
   /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
@@ -853,7 +782,89 @@ static void
 arc_override_options (void)
 {
   if (arc_cpu == PROCESSOR_NONE)
-    arc_cpu = PROCESSOR_ARC700;
+    arc_cpu = TARGET_CPU_DEFAULT;
+
+  /* Set the default cpu options.  */
+  arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
+  arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch];
+  arc_base_cpu = arc_selected_arch->arch;
+
+  /* Set the architectures.  */
+  switch (arc_selected_arch->arch)
+    {
+    case BASE_ARCH_em:
+      arc_cpu_string = "EM";
+      break;
+    case BASE_ARCH_hs:
+      arc_cpu_string = "HS";
+      break;
+    case BASE_ARCH_700:
+      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";
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  /* Set cpu flags accordingly to architecture/selected cpu.  The cpu
+     specific flags are set in arc-common.c.  The architecture forces
+     the default hardware configurations in, regardless what command
+     line options are saying.  The CPU optional hw options can be
+     turned on or off.  */
+#define ARC_OPT(NAME, CODE, MASK, DOC)			\
+  do {							\
+    if ((arc_selected_cpu->flags & CODE)		\
+	&& ((target_flags_explicit & MASK) == 0))	\
+      target_flags |= MASK;				\
+    if (arc_selected_arch->dflags & CODE)		\
+      target_flags |= MASK;				\
+  } while (0);
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)	\
+  do {						\
+    if ((arc_selected_cpu->flags & CODE)	\
+	&& (VAR == DEFAULT_##VAR))		\
+      VAR = VAL;				\
+    if (arc_selected_arch->dflags & CODE)	\
+      VAR = VAL;				\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Check options against architecture options.  Throw an error if
+     option is not allowed.  */
+#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC)			\
+  do {								\
+    if ((VAR == VAL)						\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      {								\
+	error ("%s is not available for %s architecture",	\
+	       DOC, arc_selected_arch->name);			\
+      }								\
+  } while (0);
+#define ARC_OPT(NAME, CODE, MASK, DOC)				\
+  do {								\
+    if ((target_flags & MASK)					\
+	&& (!(arc_selected_arch->flags & CODE)))		\
+      error ("%s is not available for %s architecture",		\
+	     DOC, arc_selected_arch->name);			\
+  } while (0);
+
+#include "arc-options.def"
+
+#undef ARC_OPTX
+#undef ARC_OPT
+
+  /* Set Tune option.  */
+  if (arc_tune == TUNE_NONE)
+    arc_tune = (enum attr_tune) arc_selected_cpu->tune;
 
   if (arc_size_opt_level == 3)
     optimize_size = 1;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index c02e1cd..0f97afc 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ARC_H
 #define GCC_ARC_H
 
+#include <stdbool.h>
+
 /* Things to do:
 
    - incscc, decscc?
@@ -39,6 +41,10 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
 #define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
 
+#ifndef TARGET_CPU_DEFAULT
+#define TARGET_CPU_DEFAULT	PROCESSOR_arc700
+#endif
+
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)	\
 	((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
@@ -74,9 +80,11 @@ along with GCC; see the file COPYING3.  If not see
       GNU_USER_TARGET_OS_CPP_BUILTINS (); \
     } \
   while (0)
-#endif
 
-/* Match the macros used in the assembler.  */
+#endif /* DEFAULT_LIBC == LIBC_UCLIBC */
+
+/* Macros enabled by specific command line option.  FIXME: to be
+   deprecatd.  */
 #define CPP_SPEC "\
 %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \
 %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \
@@ -85,34 +93,22 @@ along with GCC; see the file COPYING3.  If not see
 %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \
 %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \
 %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \
-%{mcpu=NPS400:-D__NPS400__} \
-%{mcpu=nps400:-D__NPS400__} \
-"
+%{mcpu=nps400:-D__NPS400__}"
 
 #define CC1_SPEC "\
 %{EB:%{EL:%emay not use both -EB and -EL}} \
 %{EB:-mbig-endian} %{EL:-mlittle-endian} \
 "
+extern const char *arc_cpu_to_as (int argc, const char **argv);
+
+#define EXTRA_SPEC_FUNCTIONS			\
+  { "cpu_to_as", arc_cpu_to_as },
+
+#define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "			\
+  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
 
-#define ASM_DEFAULT "-mARC700 -mEA"
-
-#define ASM_SPEC  "\
-%{mbig-endian|EB:-EB} %{EL} \
-%{mcpu=ARC600:-mARC600} \
-%{mcpu=ARC601:-mARC601} \
-%{mcpu=ARC700:-mARC700} \
-%{mcpu=ARC700:-mEA} \
-%{!mcpu=*:" ASM_DEFAULT "} \
-%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \
-%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \
-%{msimd} \
-%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \
-%{mcpu=ARC700|!mcpu=*:%{mlock}} \
-%{mcpu=ARC700|!mcpu=*:%{mswape}} \
-%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \
-%{mcpu=ARCHS:-mHS} \
-%{mcpu=ARCEM:-mEM} \
-%{matomic:-mlock}"
+#define OPTION_DEFAULT_SPECS						\
+  {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" }
 
 #if DEFAULT_LIBC == LIBC_UCLIBC
 /* Note that the default is to link against dynamic libraries, if they are
@@ -196,17 +192,11 @@ along with GCC; see the file COPYING3.  If not see
 #define TARGET_MMEDIUM_CALLS_DEFAULT 0
 #endif
 
-#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \
-  "%{mARC600|mA6: -mcpu=ARC600 %<mARC600 %<mA6}" \
-  "%{mARC601: -mcpu=ARC601 %<mARC601}" \
-  "%{mARC700|mA7: -mcpu=ARC700 %<mARC700 %<mA7}" \
-  "%{mbarrel_shifte*: -mbarrel-shifte%* %<mbarrel_shifte*}" \
-  "%{mEA: -mea %<mEA}" \
-  "%{mspfp_*: -mspfp-%* %<mspfp_*}" \
-  "%{mdpfp_*: -mdpfp-%* %<mdpfp_*}" \
-  "%{mdsp_pack*: -mdsp-pack%* %<mdsp_pack*}" \
-  "%{mmac_*: -mmac-%* %<mmac_*}" \
-  "%{multcost=*: -mmultcost=%* %<multcost=*}"
+#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS		   \
+  "%{mARC600|mA6: -mcpu=arc600 %<mARC600 %<mA6 %<mARC600}"	   \
+  "%{mARC601: -mcpu=arc601 %<mARC601}"				   \
+  "%{mARC700|mA7: -mcpu=arc700 %<mARC700 %<mA7}"		   \
+  "%{mEA: -mea %<mEA}"
 
 /* Run-time compilation parameters selecting different hardware subsets.  */
 
@@ -252,20 +242,21 @@ along with GCC; see the file COPYING3.  If not see
    use conditional execution?  */
 #define TARGET_AT_DBR_CONDEXEC  (!TARGET_ARC700 && !TARGET_V2)
 
-#define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
-#define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
-#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700	\
-		       || arc_cpu == PROCESSOR_NPS400)
-#define TARGET_EM     (arc_cpu == PROCESSOR_ARCEM)
-#define TARGET_HS     (arc_cpu == PROCESSOR_ARCHS)
-#define TARGET_V2							\
-  ((arc_cpu == PROCESSOR_ARCHS) || (arc_cpu == PROCESSOR_ARCEM))
-
-/* Recast the cpu class to be the cpu attribute.  */
-#define arc_cpu_attr ((enum attr_cpu)arc_cpu)
-
-#ifndef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS { "mARC700" }
+extern enum base_architecture arc_base_cpu;
+
+#define TARGET_ARC600 ((arc_base_cpu == BASE_ARCH_6xx)	\
+		       && (TARGET_BARREL_SHIFTER))
+#define TARGET_ARC601 ((arc_base_cpu == BASE_ARCH_6xx)	\
+		       && (!TARGET_BARREL_SHIFTER))
+#define TARGET_ARC700 (arc_base_cpu == BASE_ARCH_700)
+#define TARGET_EM (arc_base_cpu == BASE_ARCH_em)
+#define TARGET_HS (arc_base_cpu == BASE_ARCH_hs)
+#define TARGET_V2 (TARGET_EM || TARGET_HS)
+
+#ifdef ARC_MULTILIB_CPU_DEFAULT
+# ifndef MULTILIB_DEFAULTS
+#  define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT }
+# endif
 #endif
 
 #ifndef UNALIGNED_ACCESS_DEFAULT
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 715da31..6f757b6 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -231,11 +231,6 @@
 	 (eq_attr "is_CALL" "yes") (const_string "yes")]
 	(const_string "no")))
 
-
-;; Attribute describing the processor
-(define_attr "cpu" "none,ARC600,ARC700,ARCEM,ARCHS"
-  (const (symbol_ref "arc_cpu_attr")))
-
 ;; true for compact instructions (those with _s suffix)
 ;; "maybe" means compact unless we conditionalize the insn.
 (define_attr "iscompact" "true,maybe,true_limm,maybe_limm,false"
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 4caf366..5685100 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -54,8 +54,74 @@ Target Report
 Same as -mA7.
 
 mmpy-option=
-Target RejectNegative Joined UInteger Var(arc_mpy_option) Init(2)
--mmpy-option={0,1,2,3,4,5,6,7,8,9} Compile ARCv2 code with a multiplier design option.  Option 2 is default on.
+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)
@@ -100,7 +166,7 @@ Target Report Mask(MUL64_SET)
 Generate mul64 and mulu64 instructions.
 
 mno-mpy
-Target Report Mask(NOMPY_SET)
+Target Report Mask(NOMPY_SET) Warn(%qs is deprecated)
 Do not generate mpy instructions for ARC700.
 
 mea
@@ -167,45 +233,6 @@ mcpu=
 Target RejectNegative Joined Var(arc_cpu) Enum(processor_type) Init(PROCESSOR_NONE)
 -mcpu=CPU	Compile code for ARC variant CPU.
 
-Enum
-Name(processor_type) Type(enum processor_type)
-
-EnumValue
-Enum(processor_type) String(ARC600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(arc600) Value(PROCESSOR_ARC600)
-
-EnumValue
-Enum(processor_type) String(ARC601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(arc601) Value(PROCESSOR_ARC601)
-
-EnumValue
-Enum(processor_type) String(ARC700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700)
-
-EnumValue
-Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400)
-
-EnumValue
-Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(arcem) Value(PROCESSOR_ARCEM)
-
-EnumValue
-Enum(processor_type) String(ARCHS) Value(PROCESSOR_ARCHS)
-
-EnumValue
-Enum(processor_type) String(archs) Value(PROCESSOR_ARCHS)
-
 msize-level=
 Target RejectNegative Joined UInteger Var(arc_size_opt_level) Init(-1)
 size optimization level: 0:none 1:opportunistic 2: regalloc 3:drop align, -Os.
@@ -308,25 +335,25 @@ Expand adddi3 and subdi3 at rtl generation time into add.f / adc etc.
 ; Flags used by the assembler, but for which we define preprocessor
 ; macro symbols as well.
 mcrc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable variable polynomial CRC extension.
 
 mdsp-packa
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable DSP 3.1 Pack A extensions.
 
 mdvbf
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable dual viterbi butterfly extension.
 
 mmac-d16
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mmac-24
-Target Report Undocumented
+Target Report Undocumented Warn(%qs is deprecated)
 
 mtelephony
-Target Report RejectNegative
+Target Report RejectNegative Warn(%qs is deprecated)
 Enable Dual and Single Operand Instructions for Telephony.
 
 mxy
@@ -343,7 +370,7 @@ Target Report
 Enable swap byte ordering extension instruction.
 
 mrtsc
-Target Report
+Target Report Warn(%qs is deprecated)
 Enable 64-bit Time-Stamp Counter extension instruction.
 
 EB
@@ -394,24 +421,6 @@ Target
 multcost=
 Target RejectNegative Joined
 
-; Unfortunately, listing the full option name gives us clashes
-; with OPT_opt_name being claimed for both opt_name and opt-name,
-; so we leave out the last character or more.
-mbarrel_shifte
-Target Joined
-
-mspfp_
-Target Joined
-
-mdpfp_
-Target Joined
-
-mdsp_pack
-Target Joined
-
-mmac_
-Target Joined
-
 matomic
 Target Report Mask(ATOMIC)
 Enable atomic instructions.
@@ -421,47 +430,47 @@ Target Report Mask(LL64)
 Enable double load/store instructions for ARC HS.
 
 mfpu=
-Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(0)
+Target RejectNegative Joined Enum(arc_fpu) Var(arc_fpu_build) Init(DEFAULT_arc_fpu_build)
 Specify the name of the target floating point configuration.
 
 Enum
 Name(arc_fpu) Type(int)
 
 EnumValue
-Enum(arc_fpu) String(fpus) Value(FPU_SP | FPU_SC)
+Enum(arc_fpu) String(fpus) Value(FPU_FPUS)
 
 EnumValue
-Enum(arc_fpu) String(fpud) Value(FPU_SP | FPU_SC | FPU_DP | FPU_DC)
+Enum(arc_fpu) String(fpud) Value(FPU_FPUD)
 
 EnumValue
-Enum(arc_fpu) String(fpuda) Value(FPU_SP | FPU_SC | FPX_DP)
+Enum(arc_fpu) String(fpuda) Value(FPU_FPUDA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_div) Value(FPU_SP | FPU_SC | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_div) Value(FPU_FPUDA_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPX_DP)
+Enum(arc_fpu) String(fpuda_fma) Value(FPU_FPUDA_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpuda_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP)
+Enum(arc_fpu) String(fpuda_all) Value(FPU_FPUDA_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpus_div) Value(FPU_SP | FPU_SC | FPU_SD)
+Enum(arc_fpu) String(fpus_div) Value(FPU_FPUS_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpud_div) Value(FPU_SP | FPU_SC | FPU_SD | FPU_DP | FPU_DC | FPU_DD)
+Enum(arc_fpu) String(fpud_div) Value(FPU_FPUD_DIV)
 
 EnumValue
-Enum(arc_fpu) String(fpus_fma) Value(FPU_SP | FPU_SC | FPU_SF)
+Enum(arc_fpu) String(fpus_fma) Value(FPU_FPUS_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpud_fma) Value(FPU_SP | FPU_SC | FPU_SF | FPU_DP | FPU_DC | FPU_DF)
+Enum(arc_fpu) String(fpud_fma) Value(FPU_FPUD_FMA)
 
 EnumValue
-Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
+Enum(arc_fpu) String(fpus_all) Value(FPU_FPUS_ALL)
 
 EnumValue
-Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL)
 
 mtp-regno=
 Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25)
diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c
new file mode 100644
index 0000000..0c24cda
--- /dev/null
+++ b/gcc/config/arc/driver-arc.c
@@ -0,0 +1,81 @@
+/* Subroutines for the gcc driver.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+   Contributed by Claudiu Zissulescu <claziss@synopsys.com>
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING3.  If not see
+   <http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+/* Returns command line parameters to pass to as.  */
+
+const char*
+arc_cpu_to_as (int argc, const char **argv)
+{
+  const char *name = NULL;
+  const arc_cpu_t *arc_selected_cpu;
+
+  /* No argument, check what is the default cpu.  */
+  if (argc == 0)
+    {
+      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
+    }
+  else
+    {
+      name = argv[0];
+      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
+	   arc_selected_cpu++)
+	{
+	  if (strcmp (arc_selected_cpu->name, name) == 0)
+	    break;
+	}
+    }
+
+  switch (arc_selected_cpu->arch)
+    {
+    case BASE_ARCH_em:
+      if (arc_selected_cpu->flags & FL_CD)
+	name = "-mcode-density";
+      else
+	name = "";
+      if (arc_selected_cpu->flags & FL_FPUDA)
+	name = concat ("-mfpuda ", name, NULL);
+      if (arc_selected_cpu->flags & FL_SPFP)
+	name = concat ("-mspfp ", name, NULL);
+      if (arc_selected_cpu->flags & FL_DPFP)
+	name = concat ("-mdpfp ", name, NULL);
+      return concat ("-mcpu=arcem ", name, NULL);
+    case BASE_ARCH_hs:
+      return "-mcpu=archs";
+    case BASE_ARCH_700:
+      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";
+      if (arc_selected_cpu->flags & FL_MUL32x16)
+	return "-mcpu=arc600 -mdsp-packa -mnorm";
+      return "-mcpu=arc600 -mnorm";
+    default:
+      gcc_unreachable ();
+    }
+  return NULL;
+}
diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk
new file mode 100644
index 0000000..5934f4f
--- /dev/null
+++ b/gcc/config/arc/genmultilib.awk
@@ -0,0 +1,203 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+# Transform CPU Information from arc-cpu.def to a
+# Representation that is understood by GCC's multilib Machinery.
+#
+# The Script works as a Filter from STDIN to STDOUT.
+#
+# FORMAT = "Makefile": Generate Makefile Snipet that sets some
+#                      MULTILIB_* Variables as needed.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+  n_reuse = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "# Auto-generated Makefile Snip"
+	  print "# Generated by    : ./gcc/config/arc/genmultilib.awk"
+	  print "# Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print "# Used by         : tmake_file from Makefile and genmultilib"
+	  print ""
+	}
+    }
+
+  comment = 2;
+
+  print
+}
+
+/^$/ {
+  # The first empty line stops copy-pasting the GPL comments
+  # from this file to the generated file.
+
+  comment = 0
+}
+
+
+/^ARC_CPU/ {
+  name = $2
+  #  gsub ("\"", "", name)
+
+  if ($4 != "0")
+    {
+      arch = $3
+      if (arch == "6xx")
+	arch = 601
+
+      n = split ($4, cpu_flg, "|")
+
+      line = "mcpu." arch
+      for (i = 1; i <= n; i++)
+	{
+	  if (cpu_flg[i] == "FL_MPYOPT_0")
+	    line = line "/mmpy-option.0"
+	  else if (cpu_flg[i] == "FL_MPYOPT_1")
+	    line = line "/mmpy-option.1"
+	  else if (cpu_flg[i] == "FL_MPYOPT_2")
+	    line = line "/mmpy-option.2"
+	  else if (cpu_flg[i] == "FL_MPYOPT_3")
+	    line = line "/mmpy-option.3"
+	  else if (cpu_flg[i] == "FL_MPYOPT_4")
+	    line = line "/mmpy-option.4"
+	  else if (cpu_flg[i] == "FL_MPYOPT_5")
+	    line = line "/mmpy-option.5"
+	  else if (cpu_flg[i] == "FL_MPYOPT_6")
+	    line = line "/mmpy-option.6"
+	  else if (cpu_flg[i] == "FL_MPYOPT_7")
+	    line = line "/mmpy-option.7"
+	  else if (cpu_flg[i] == "FL_MPYOPT_8")
+	    line = line "/mmpy-option.8"
+	  else if (cpu_flg[i] == "FL_MPYOPT_9")
+	    line = line "/mmpy-option.9"
+	  else if (cpu_flg[i] == "FL_CD")
+	    line = line "/mcode-density"
+	  else if (cpu_flg[i] == "FL_BS")
+	    line = line "/mbarrel-shifter"
+	  else if (cpu_flg[i] == "FL_DIVREM")
+	    line = line "/mdiv-rem"
+	  else if (cpu_flg[i] == "FL_NORM" \
+		   || cpu_flg[i] == "FL_SWAP")
+	    line = line "/mnorm"
+	  else if (cpu_flg[i] == "FL_FPU_FPUS")
+	    line = line "/mfpu.fpus"
+	  else if (cpu_flg[i] == "FL_FPU_FPUDA")
+	    line = line "/mfpu.fpuda"
+	  else if (cpu_flg[i] == "FL_FPU_FPUD_ALL")
+	    line = line "/mfpu.fpud_all"
+	  else if (cpu_flg[i] == "FL_LL64")
+	    line = line "/mll64"
+	  else if (cpu_flg[i] == "FL_MUL64")
+	    line = line "/mmul64"
+	  else if (cpu_flg[i] == "FL_MUL32x16")
+	    line = line "/mmul32x16"
+	  else if (cpu_flg[i] == "FL_FPX_QUARK")
+	    line = line "/quark"
+	  else if (cpu_flg[i] == "FL_SPFP")
+	    line = line "/spfp"
+	  else if (cpu_flg[i] == "FL_DPFP")
+	    line = line "/dpfp"
+	  else
+	    {
+	      print "Don't know the flag " cpu_flg[i] > "/dev/stderr"
+	      exit 1
+	    }
+	}
+      line = "mcpu." name "=" line
+      reuse[n_reuse] = line
+      n_reuse++
+    }
+
+  core = name
+  cores[n_cores] = core
+  n_cores++
+}
+
+##################################################################
+#
+# We gathered all the Information, now build/output the following:
+#
+#    awk Variable         target Variable          FORMAT
+#  -----------------------------------------------------------
+#    m_options     <->    MULTILIB_OPTIONS         Makefile
+#    m_dirnames    <->    MULTILIB_DIRNAMES           "
+#
+##################################################################
+
+END {
+  m_options    = "\nMULTILIB_OPTIONS = "
+  m_dirnames   = "\nMULTILIB_DIRNAMES ="
+  m_reuse      = "\nMULTILIB_REUSE ="
+
+  sep = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options  = m_options sep "mcpu=" cores[c]
+      m_dirnames = m_dirnames " " cores[c]
+      sep = "/"
+    }
+
+  sep = ""
+  for (c = 0; c < n_reuse; c++)
+    {
+      m_reuse = m_reuse sep reuse[c]
+      sep = "\nMULTILIB_REUSE +="
+    }
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+      # Intended Target: ./gcc/config/arc/t-multilib
+
+      print m_options
+      print m_dirnames
+
+      ############################################################
+      # Legacy Aliases
+      ############################################################
+
+      print ""
+      print "# Aliases:"
+      print "MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mARC600"
+      print "MULTILIB_MATCHES += mcpu?arc600=mA6"
+      print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601"
+      print "MULTILIB_MATCHES += mcpu?arc700=mA7"
+      print "MULTILIB_MATCHES += mcpu?arc700=mARC700"
+    }
+}
diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk
new file mode 100644
index 0000000..24a93eb
--- /dev/null
+++ b/gcc/config/arc/genoptions.awk
@@ -0,0 +1,86 @@
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+##################################################################
+#
+# This file is using AVR's genmultilib.awk idea.
+#
+##################################################################
+
+BEGIN {
+  FS ="[(, \t)]+"
+  comment = 1
+  n_cores = 0
+}
+
+##################################################################
+# Add some Comments to the generated Files and copy-paste
+# Copyright Notice from above.
+##################################################################
+/^#/ {
+  if (!comment)
+    next
+  else if (comment == 1)
+    {
+      if (FORMAT == "Makefile")
+	{
+	  print "; Auto-generated Makefile Snip"
+	  print "; Generated by    : ./gcc/config/arc/genoptions.awk"
+	  print "; Generated from  : ./gcc/config/arc/arc-cpu.def"
+	  print ";"
+	}
+    }
+
+  comment = 2;
+
+  gsub ("^#", ";", $0)
+  print
+}
+
+/^$/ {
+    # The first empty line stops copy-pasting the GPL comments
+    # from this file to the generated file.
+    comment = 0
+}
+
+/^ARC_CPU/ {
+  name = $2
+  cores[n_cores] = name;
+  n_cores++
+}
+
+END {
+  m_option = ""
+  for (c = 0; c < n_cores; c++)
+    {
+      m_options = m_options "EnumValue\nEnum(processor_type) String(" \
+	cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n"
+    }
+
+  ############################################################
+  # Output that Stuff
+  ############################################################
+
+  if (FORMAT == "Makefile")
+    {
+	print "\nEnum"
+	print "Name(processor_type) Type(enum processor_type)"
+	print "Known ARC CPUs (for use with the -mcpu= option):\n"
+	print m_options
+    }
+}
diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc
index 4252e73..bdb1328 100644
--- a/gcc/config/arc/t-arc
+++ b/gcc/config/arc/t-arc
@@ -19,11 +19,30 @@
 
 TM_H += $(srcdir)/config/arc/arc-c.def
 
+driver-arc.o: $(srcdir)/config/arc/driver-arc.c \
+  $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
+	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
 arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \
 $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/arc/arc-c.c
 
+#Run `arc-cpus` if you changed something in arc-cpus.def
+
+.PHONY: arc-cpus
+
+arc-cpus: $(srcdir)/config/arc/t-multilib \
+	$(srcdir)/config/arc/arc-tables.opt
+
+$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk 	\
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
+$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \
+				 $(srcdir)/config/arc/arc-cpus.def
+	$(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@
+
 # Local Variables:
 # mode: Makefile
 # End:
diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib
deleted file mode 100644
index c49a3fcc..0000000
--- a/gcc/config/arc/t-arc-newlib
+++ /dev/null
@@ -1,46 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with newlib.
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm
-MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm
-#
-# Aliases:
-MULTILIB_MATCHES  = mcpu?ARC600=mcpu?arc600
-MULTILIB_MATCHES += mcpu?ARC600=mARC600
-MULTILIB_MATCHES += mcpu?ARC600=mA6
-MULTILIB_MATCHES += mcpu?ARC600=mno-mpy
-MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601
-MULTILIB_MATCHES += mcpu?ARC700=mA7
-MULTILIB_MATCHES += mcpu?ARC700=mARC700
-MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700
-MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem
-MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs
-MULTILIB_MATCHES += EL=mlittle-endian
-MULTILIB_MATCHES += EB=mbig-endian
-#
-# These don't make sense for the ARC700 default target:
-MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm*
-# And neither of the -mmul* options make sense without -mnorm:
-MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm
-# Exclusions for ARC700
-MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16*
-# Exclusions for ARCv2EM
-MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16*
-# Exclusions for ARCv2HS
-MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm*
diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-arc-uClibc
deleted file mode 100644
index 11e81f1..0000000
--- a/gcc/config/arc/t-arc-uClibc
+++ /dev/null
@@ -1,20 +0,0 @@
-# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
-
-# Copyright (C) 2007-2016 Free Software Foundation, Inc.
-
-# This file is part of GCC.
-
-# GCC is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3, or (at your option) any later version.
-
-# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-# details.
-
-# You should have received a copy of the GNU General Public License along
-# with GCC; see the file COPYING3.  If not see
-# <http://www.gnu.org/licenses/>.
-
-MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib
new file mode 100644
index 0000000..5a36af6
--- /dev/null
+++ b/gcc/config/arc/t-multilib
@@ -0,0 +1,34 @@
+# Auto-generated Makefile Snip
+# Generated by    : ./gcc/config/arc/genmultilib.awk
+# Generated from  : ./gcc/config/arc/arc-cpu.def
+# Used by         : tmake_file from Makefile and genmultilib
+
+# Copyright (C) 2016 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+#
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400
+
+MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400
+
+# Aliases:
+MULTILIB_MATCHES  = mcpu?arc600=mcpu?ARC600
+MULTILIB_MATCHES += mcpu?arc600=mARC600
+MULTILIB_MATCHES += mcpu?arc600=mA6
+MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601
+MULTILIB_MATCHES += mcpu?arc700=mA7
+MULTILIB_MATCHES += mcpu?arc700=mARC700
diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc
new file mode 100644
index 0000000..11e81f1
--- /dev/null
+++ b/gcc/config/arc/t-uClibc
@@ -0,0 +1,20 @@
+# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc
+
+# Copyright (C) 2007-2016 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation; either version 3, or (at your option) any later version.
+
+# GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
+# details.
+
+# You should have received a copy of the GNU General Public License along
+# with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+MULTILIB_EXTRA_OPTS = mno-sdata
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 3f9c0a0..4399733 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -13882,29 +13882,92 @@ values for @var{cpu} are
 @table @samp
 @opindex mA6
 @opindex mARC600
-@item ARC600
 @item arc600
 Compile for ARC600.  Aliases: @option{-mA6}, @option{-mARC600}.
 
-@item ARC601
 @item arc601
 @opindex mARC601
 Compile for ARC601.  Alias: @option{-mARC601}.
 
-@item ARC700
 @item arc700
 @opindex mA7
 @opindex mARC700
 Compile for ARC700.  Aliases: @option{-mA7}, @option{-mARC700}.
 This is the default when configured with @option{--with-cpu=arc700}@.
 
-@item ARCEM
 @item arcem
 Compile for ARC EM.
 
-@item ARCHS
 @item archs
 Compile for ARC HS.
+
+@item em
+@opindex em
+Compile for ARC EM cpu with no hardware extension.
+
+@item em4
+@opindex em4
+Compile for ARC EM4 cpu.
+
+@item em4_dmips
+@opindex em4_dmips
+Compile for ARC EM4 DMIPS cpu.
+
+@item em4_fpus
+@opindex em4_fpus
+Compile for ARC EM4 DMIPS cpu with single precision floating point
+extension.
+
+@item em4_fpuda
+@opindex em4_fpuda
+Compile for ARC EM4 DMIPS cpu with single precision floating point and
+double assists instructions.
+
+@item hs
+@opindex hs
+Compile for ARC HS cpu with no hardware extension, except the atomic
+instructions.
+
+@item hs34
+@opindex hs34
+Compile for ARC HS34 cpu.
+
+@item hs38
+@opindex hs38
+Compile for ARC HS38 cpu.
+
+@item hs38_linux
+@opindex hs38_linux
+Compile for ARC HS38 cpu with all hardware extensions on.
+
+@item arc600_norm
+@opindex arc600_norm
+Compile for ARC 600 cpu with norm instruction enabled.
+
+@item arc600_mul32x16
+@opindex arc600_mul32x16
+Compile for ARC 600 cpu with norm and mul32x16 instructions enabled.
+
+@item arc600_mul64
+@opindex arc600_mul64
+Compile for ARC 600 cpu with norm and mul64 instructions enabled.
+
+@item arc601_norm
+@opindex arc601_norm
+Compile for ARC 601 cpu with norm instruction enabled.
+
+@item arc601_mul32x16
+@opindex arc601_mul32x16
+Compile for ARC 601 cpu with norm and mul32x16 instructions enabled.
+
+@item arc601_mul64
+@opindex arc601_mul64
+Compile for ARC 601 cpu with norm and mul64 instructions enabled.
+
+@item nps400
+@opindex nps400
+Compile for ARC 700 on NPS400 chip.
+
 @end table
 
 @item -mdpfp
@@ -13931,7 +13994,8 @@ supported.  This is always enabled for @option{-mcpu=ARC700}.
 
 @item -mno-mpy
 @opindex mno-mpy
-Do not generate mpy instructions for ARC700.
+Do not generate mpy instructions for ARC700.  This instruction is
+deprecated.
 
 @item -mmul32x16
 @opindex mmul32x16
@@ -14138,12 +14202,14 @@ define preprocessor macro symbols.
 @item -mdsp-packa
 @opindex mdsp-packa
 Passed down to the assembler to enable the DSP Pack A extensions.
-Also sets the preprocessor symbol @code{__Xdsp_packa}.
+Also sets the preprocessor symbol @code{__Xdsp_packa}.  This option is
+deprecated.
 
 @item -mdvbf
 @opindex mdvbf
 Passed down to the assembler to enable the dual viterbi butterfly
-extension.  Also sets the preprocessor symbol @code{__Xdvbf}.
+extension.  Also sets the preprocessor symbol @code{__Xdvbf}.  This
+option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mlock
@@ -14155,19 +14221,19 @@ Conditional extension.  Also sets the preprocessor symbol
 @item -mmac-d16
 @opindex mmac-d16
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_d16}.
+@code{__Xxmac_d16}.  This option is deprecated.
 
 @item -mmac-24
 @opindex mmac-24
 Passed down to the assembler.  Also sets the preprocessor symbol
-@code{__Xxmac_24}.
+@code{__Xxmac_24}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mrtsc
 @opindex mrtsc
 Passed down to the assembler to enable the 64-bit Time-Stamp Counter
 extension instruction.  Also sets the preprocessor symbol
-@code{__Xrtsc}.
+@code{__Xrtsc}.  This option is deprecated.
 
 @c ARC700 4.10 extension instruction
 @item -mswape
@@ -14180,7 +14246,7 @@ extension instruction.  Also sets the preprocessor symbol
 @opindex mtelephony
 Passed down to the assembler to enable dual and single operand
 instructions for telephony.  Also sets the preprocessor symbol
-@code{__Xtelephony}.
+@code{__Xtelephony}.  This option is deprecated.
 
 @item -mxy
 @opindex mxy
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" } } */
-- 
1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH] [ARC] New option handling, refurbish multilib support.
       [not found]                 ` <20161115123637.GB5975@embecosm.com>
@ 2016-11-15 15:11                   ` Claudiu Zissulescu
  0 siblings, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-11-15 15:11 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches

> This looks fine.  Thanks for all your effort revising this patch.
> 
> Andrew
> 

Committed r242425. 

Thank you for your review,
Claudiu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 2/2] [ARC] Update target specific tests.
  2016-05-30 14:21 ` [PATCH 2/2] [ARC] Update target specific tests Claudiu Zissulescu
@ 2016-11-15 15:23   ` Claudiu Zissulescu
  2016-11-16 15:58   ` Andrew Burgess
  1 sibling, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-11-15 15:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: Francois.Bedard, andrew.burgess

PING! Once the new options are in, we need also to update the tests. 

Andrew, please can you check it,
Claudiu

> -----Original Message-----
> From: Claudiu Zissulescu
> Sent: Monday, May 30, 2016 2:33 PM
> To: gcc-patches@gcc.gnu.org
> Cc: Claudiu Zissulescu <claziss@synopsys.com>; gnu@amylaar.uk;
> Francois.Bedard@synopsys.com
> Subject: [PATCH 2/2] [ARC] Update target specific tests.
> 
> Update the ARC specific tests.
> 
> OK to apply?
> Claudiu
> 
> gcc/
> 2016-05-26  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* testsuite/gcc.target/arc/abitest.S: New file.
> 	* testsuite/gcc.target/arc/va_args-1.c: Likewise.
> 	* testsuite/gcc.target/arc/va_args-2.c: Likewise.
> 	* testsuite/gcc.target/arc/va_args-3.c: Likewise.
> 	* testsuite/gcc.target/arc/mcrc.c: Deleted.
> 	* testsuite/gcc.target/arc/mdsp-packa.c: Likewise.
> 	* testsuite/gcc.target/arc/mdvbf.c: Likewise.
> 	* testsuite/gcc.target/arc/mmac-24.c: Likewise.
> 	* testsuite/gcc.target/arc/mmac-d16.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-crc.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-dsp-packa.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-dvbf.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-mac-24.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-mac-d16.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-rtsc.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-xy.c: Likewise.
> 	* testsuite/gcc.target/arc/mrtsc.c: Likewise.
> 	* testsuite/gcc.target/arc/arc.exp (check_effective_target_arcem):
> 	New function.
> 	(check_effective_target_arc700): Likewise.
> 	(check_effective_target_arc6xx): Likewise.
> 	(check_effective_target_arcmpy): Likewise.
> 	(check_effective_target_archs): Likewise.
> 	(check_effective_target_clmcpu): Likewise.
> 	* testsuite/gcc.target/arc/barrel-shifter-1.c: Changed.
> 	* testsuite/gcc.target/arc/builtin_simd.c: Test only for ARC700
> 	cpus.
> 	* testsuite/gcc.target/arc/cmem-1.c: Changed.
> 	* testsuite/gcc.target/arc/cmem-2.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-3.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-4.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-5.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-6.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-7.c: Likewise.
> 	* testsuite/gcc.target/arc/interrupt-1.c: Test for RTIE as well.
> 	* testsuite/gcc.target/arc/interrupt-2.c: Skip it for ARCv2 cores.
> 	* testsuite/gcc.target/arc/interrupt-3.c: Match also ARCv2
> 	warnings.
> 	* testsuite/gcc.target/arc/jump-around-jump.c: Update options.
> 	* testsuite/gcc.target/arc/mARC601.c: Changed.
> 	* testsuite/gcc.target/arc/mcpu-arc600.c: Changed.
> 	* testsuite/gcc.target/arc/mcpu-arc601.c: Changed.
> 	* testsuite/gcc.target/arc/mcpu-arc700.c: Changed.
> 	* testsuite/gcc.target/arc/mdpfp.c: Skip for ARCv2 cores.
> 	* testsuite/gcc.target/arc/movb-1.c: Changed.
> 	* testsuite/gcc.target/arc/movb-2.c: Likewise.
> 	* testsuite/gcc.target/arc/movb-3.c: Likewise.
> 	* testsuite/gcc.target/arc/movb-4.c: Likewise.
> 	* testsuite/gcc.target/arc/movb-5.c: Likewise.
> 	* testsuite/gcc.target/arc/movb_cl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/movb_cl-2.c: Likewise.
> 	* testsuite/gcc.target/arc/movbi_cl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/movh_cl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/mspfp.c: Skip for ARC HS cores.
> 	* testsuite/gcc.target/arc/mul64.c: Enable it only for ARC600.
> 	* testsuite/gcc.target/arc/mulsi3_highpart-1.c: Scan for ARCv2
> 	instructions.
> 	* testsuite/gcc.target/arc/mulsi3_highpart-2.c: Skip it for ARCv1
> 	cores.
> 	* testsuite/gcc.target/arc/no-dpfp-lrsr.c: Skip it for ARC HS.
> 	* testsuite/gcc.target/arc/trsub.c: Only for ARC EM cores.
> 	* testsuite/gcc.target/arc/builtin_simdarc.c: Changed.
> 	* testsuite/gcc.target/arc/extzv-1.c: Likewise.
> 	* testsuite/gcc.target/arc/insv-1.c: Likewise.
> 	* testsuite/gcc.target/arc/insv-2.c: Likewise.
> 	* testsuite/gcc.target/arc/mA6.c: Likewise.
> 	* testsuite/gcc.target/arc/mA7.c: Likewise.
> 	* testsuite/gcc.target/arc/mARC600.c: Likewise.
> 	* testsuite/gcc.target/arc/mARC700.c: Likewise.
> 	* testsuite/gcc.target/arc/mcpu-arc600.c: Likewise.
> 	* testsuite/gcc.target/arc/mcpu-arc700.c: Likewise.
> 	* testsuite/gcc.target/arc/movl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/nps400-1.c: Likewise.
> 	* testsuite/gcc.target/arc/trsub.c: Likewise.
> ---
>  gcc/testsuite/gcc.target/arc/abitest.S           | 31 +++++++++++
>  gcc/testsuite/gcc.target/arc/arc.exp             | 66
> +++++++++++++++++++++++-
>  gcc/testsuite/gcc.target/arc/barrel-shifter-1.c  |  2 +-
>  gcc/testsuite/gcc.target/arc/builtin_simd.c      |  1 +
>  gcc/testsuite/gcc.target/arc/builtin_simdarc.c   |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-2.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-3.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-4.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-5.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-6.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-7.c            |  1 +
>  gcc/testsuite/gcc.target/arc/extzv-1.c           |  1 +
>  gcc/testsuite/gcc.target/arc/insv-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/insv-2.c            |  1 +
>  gcc/testsuite/gcc.target/arc/interrupt-1.c       |  7 ++-
>  gcc/testsuite/gcc.target/arc/interrupt-2.c       |  1 +
>  gcc/testsuite/gcc.target/arc/interrupt-3.c       |  2 +-
>  gcc/testsuite/gcc.target/arc/jump-around-jump.c  |  2 +-
>  gcc/testsuite/gcc.target/arc/mA6.c               |  1 +
>  gcc/testsuite/gcc.target/arc/mA7.c               |  1 +
>  gcc/testsuite/gcc.target/arc/mARC600.c           |  1 +
>  gcc/testsuite/gcc.target/arc/mARC601.c           |  3 +-
>  gcc/testsuite/gcc.target/arc/mARC700.c           |  1 +
>  gcc/testsuite/gcc.target/arc/mcpu-arc600.c       |  3 +-
>  gcc/testsuite/gcc.target/arc/mcpu-arc601.c       |  5 +-
>  gcc/testsuite/gcc.target/arc/mcpu-arc700.c       |  3 +-
>  gcc/testsuite/gcc.target/arc/mcrc.c              |  8 ---
>  gcc/testsuite/gcc.target/arc/mdpfp.c             |  1 +
>  gcc/testsuite/gcc.target/arc/mdsp-packa.c        |  9 ----
>  gcc/testsuite/gcc.target/arc/mdvbf.c             |  9 ----
>  gcc/testsuite/gcc.target/arc/mmac-24.c           |  8 ---
>  gcc/testsuite/gcc.target/arc/mmac-d16.c          |  9 ----
>  gcc/testsuite/gcc.target/arc/mno-crc.c           | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-dsp-packa.c     | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-dvbf.c          | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-mac-24.c        | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-mac-d16.c       | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-rtsc.c          | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-xy.c            | 10 ----
>  gcc/testsuite/gcc.target/arc/movb-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-2.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-3.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-4.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-5.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb_cl-1.c         |  1 +
>  gcc/testsuite/gcc.target/arc/movb_cl-2.c         |  1 +
>  gcc/testsuite/gcc.target/arc/movbi_cl-1.c        |  1 +
>  gcc/testsuite/gcc.target/arc/movh_cl-1.c         |  1 +
>  gcc/testsuite/gcc.target/arc/movl-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/mrtsc.c             |  8 ---
>  gcc/testsuite/gcc.target/arc/mspfp.c             |  1 +
>  gcc/testsuite/gcc.target/arc/mul64.c             |  3 +-
>  gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c |  5 +-
>  gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c |  4 +-
>  gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c      |  1 +
>  gcc/testsuite/gcc.target/arc/nps400-1.c          |  1 +
>  gcc/testsuite/gcc.target/arc/trsub.c             |  1 +
>  gcc/testsuite/gcc.target/arc/va_args-1.c         | 16 ++++++
>  gcc/testsuite/gcc.target/arc/va_args-2.c         | 14 +++++
>  gcc/testsuite/gcc.target/arc/va_args-3.c         | 15 ++++++
>  61 files changed, 198 insertions(+), 142 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/abitest.S
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mcrc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mdsp-packa.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mdvbf.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-24.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-d16.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-crc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dvbf.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-24.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-d16.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-rtsc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-xy.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mrtsc.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-1.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-2.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-3.c
> 
> diff --git a/gcc/testsuite/gcc.target/arc/abitest.S
> b/gcc/testsuite/gcc.target/arc/abitest.S
> new file mode 100644
> index 0000000..7be935b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/abitest.S
> @@ -0,0 +1,31 @@
> +/* { dg-do assemble } */
> +#ifndef ENTRY
> +#define ENTRY(nm)               \
> +        .text `                 \
> +        .align 4 `              \
> +        .globl nm `             \
> +        .type nm,@function `    \
> +nm:
> +#endif
> +
> +#ifndef END
> +#define END(name)       .size name,.-name
> +#endif
> +
> +ENTRY(tsyscall)
> +ENTRY(clone)
> +	add	r0,r0,r1
> +	add	r0,r0,r2
> +	add	r0,r0,r3
> +	add	r0,r0,r4
> +	add	r0,r0,r5
> +	j_s.d	[blink]
> +	add	r0,r0,r6
> +END(tsyscall)
> +END(clone)
> +
> +ENTRY(abidi)
> +	add.f r0,r1,1
> +        j_s.d [blink]
> +        adc r1,r2,0
> +END(abidi)
> diff --git a/gcc/testsuite/gcc.target/arc/arc.exp
> b/gcc/testsuite/gcc.target/arc/arc.exp
> index fae2ece7..3b7d100 100644
> --- a/gcc/testsuite/gcc.target/arc/arc.exp
> +++ b/gcc/testsuite/gcc.target/arc/arc.exp
> @@ -4,12 +4,12 @@
>  # it under the terms of the GNU General Public License as published by
>  # the Free Software Foundation; either version 3 of the License, or
>  # (at your option) any later version.
> -#
> +#
>  # This program is distributed in the hope that it will be useful,
>  # but WITHOUT ANY WARRANTY; without even the implied warranty of
>  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  # GNU General Public License for more details.
> -#
> +#
>  # You should have received a copy of the GNU General Public License
>  # along with GCC; see the file COPYING3.  If not see
>  # <http://www.gnu.org/licenses/>.
> @@ -24,6 +24,68 @@ if ![istarget arc*-*-*] then {
>  # Load support procs.
>  load_lib gcc-dg.exp
> 
> +# Return 1 if this is a compiler supporting ARCv2 EM as default processor
> +proc check_effective_target_arcem { } {
> +    return [check_no_compiler_messages arcem assembly {
> +	#if !defined (__ARCEM__)
> +	#error No ARC EM
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if we compile for ARC700
> +proc check_effective_target_arc700 { } {
> +    return [check_no_compiler_messages arc700 assembly {
> +	#if !defined (__ARC700__)
> +	#error No ARC 700
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if we compile for ARC6xx
> +proc check_effective_target_arc6xx { } {
> +    return [check_no_compiler_messages arc6xx assembly {
> +	#if !defined (__ARC600__) && !defined (__ARC601__)
> +	#error No ARC 6xx
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if we have mpy
> +proc check_effective_target_arcmpy { } {
> +    return [check_no_compiler_messages arcmpy assembly {
> +	#if !defined (__ARC_MPY__)
> +	#error No MPY
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if this is a compiler supporting ARC HS as default processor
> +proc check_effective_target_archs { } {
> +    return [check_no_compiler_messages archs assembly {
> +	#if !defined (__ARCHS__)
> +	#error No ARC HS
> +	#endif
> +    }]
> +}
> +
> +proc check_cl { flags } {
> +    return [check_no_compiler_messages check_$flags assembly {
> +	#if !defined (__arc__)
> +	#error Extra mcpu options
> +	#endif
> +    } "$flags"]
> +}
> +
> +# Return 1 if there are no extra mcpu options given via command line
> +proc check_effective_target_clmcpu { } {
> +    if { [check_cl "-mcpu=arc700"]
> +	 && [check_cl "-mcpu=arcem" ] } {
> +	return 1
> +    }
> +    return 0
> +}
> +
>  # If a testcase doesn't have special options, use these.
>  global DEFAULT_CFLAGS
>  if ![info exists DEFAULT_CFLAGS] then {
> diff --git a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
> b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
> index a0eb6d7..5cfb282 100644
> --- a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
> +++ b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -mcpu=ARC601 -mbarrel-shifter" } */
> +/* { dg-options "-O2 -mbarrel-shifter" } */
>  int i;
> 
>  int f (void)
> diff --git a/gcc/testsuite/gcc.target/arc/builtin_simd.c
> b/gcc/testsuite/gcc.target/arc/builtin_simd.c
> index fff27a4..6b02521 100644
> --- a/gcc/testsuite/gcc.target/arc/builtin_simd.c
> +++ b/gcc/testsuite/gcc.target/arc/builtin_simd.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-O2 -Werror-implicit-function-declaration -mARC700 -
> msimd" } */
> 
>  #define STEST1(name, rettype, op1)		\
> diff --git a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
> b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
> index 68aae40..0cfe2ad 100644
> --- a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
> +++ b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=archs -O2 -Werror-implicit-function-declaration -
> mmpy-option=9" } */
> 
>  #define STEST(name, rettype, op1type, op2type)	\
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c
> b/gcc/testsuite/gcc.target/arc/cmem-1.c
> index 7f36afb..8ed5dcf 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-1.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
> 
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c
> b/gcc/testsuite/gcc.target/arc/cmem-2.c
> index a3d7c130..39bfb28 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-2.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
> 
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c
> b/gcc/testsuite/gcc.target/arc/cmem-3.c
> index dee73b5..109084f 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-3.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-3.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
> 
>  #define CMEM_SECTION_ATTR __attribute__ ((section
> (".cmem_private")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c
> b/gcc/testsuite/gcc.target/arc/cmem-4.c
> index 1da6bce..4ac8a22 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-4.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-4.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
> 
>  #define CMEM_SECTION_ATTR __attribute__ ((section
> (".cmem_private")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c
> b/gcc/testsuite/gcc.target/arc/cmem-5.c
> index ad6904f..451218b 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-5.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-5.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
> 
>  #define CMEM_SECTION_ATTR __attribute__ ((section
> (".cmem_shared")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c
> b/gcc/testsuite/gcc.target/arc/cmem-6.c
> index 24bc39b..0ed0608 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-6.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-6.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
> 
>  #define CMEM_SECTION_ATTR __attribute__ ((section
> (".cmem_shared")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c
> b/gcc/testsuite/gcc.target/arc/cmem-7.c
> index 72ee7bd..0267327 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-7.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-7.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
> 
>  struct some_struct
> diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c
> b/gcc/testsuite/gcc.target/arc/extzv-1.c
> index 242f522..1e5533a7 100644
> --- a/gcc/testsuite/gcc.target/arc/extzv-1.c
> +++ b/gcc/testsuite/gcc.target/arc/extzv-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct foo { unsigned a: 3, b: 5, c: 24; };
> diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c
> b/gcc/testsuite/gcc.target/arc/insv-1.c
> index 75d47e9..29e4188 100644
> --- a/gcc/testsuite/gcc.target/arc/insv-1.c
> +++ b/gcc/testsuite/gcc.target/arc/insv-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  /* ??? Irrespective of insn set, generated code for this is a mess.  */
> diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c
> b/gcc/testsuite/gcc.target/arc/insv-2.c
> index 1652551..620acec 100644
> --- a/gcc/testsuite/gcc.target/arc/insv-2.c
> +++ b/gcc/testsuite/gcc.target/arc/insv-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct foo { unsigned a: 3, b: 8, c: 21; } bar;
> diff --git a/gcc/testsuite/gcc.target/arc/interrupt-1.c
> b/gcc/testsuite/gcc.target/arc/interrupt-1.c
> index 7051457..8a2002b 100644
> --- a/gcc/testsuite/gcc.target/arc/interrupt-1.c
> +++ b/gcc/testsuite/gcc.target/arc/interrupt-1.c
> @@ -1,5 +1,10 @@
> +#if defined (__ARCHS__) || defined (__ARCEM__)
> +void __attribute__ ((interrupt("ilink")))
> +#else
>  void __attribute__ ((interrupt("ilink1")))
> +#endif
>  handler1 (void)
>  {
>  }
> -/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 } } */
> +/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 { target { arc700 ||
> arc6xx } } } } */
> +/* { dg-final { scan-assembler-times "rtie" 1 { target { arcem || archs } } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/interrupt-2.c
> b/gcc/testsuite/gcc.target/arc/interrupt-2.c
> index ee8593b..285ebd5 100644
> --- a/gcc/testsuite/gcc.target/arc/interrupt-2.c
> +++ b/gcc/testsuite/gcc.target/arc/interrupt-2.c
> @@ -1,3 +1,4 @@
> +/* { dg-skip-if "ilink2 is not an ARCv2 register" { archs || arcem } } */
>  void __attribute__ ((interrupt("ilink2")))
>  handler1 (void)
>  {
> diff --git a/gcc/testsuite/gcc.target/arc/interrupt-3.c
> b/gcc/testsuite/gcc.target/arc/interrupt-3.c
> index fa598d6..b0cad88 100644
> --- a/gcc/testsuite/gcc.target/arc/interrupt-3.c
> +++ b/gcc/testsuite/gcc.target/arc/interrupt-3.c
> @@ -5,7 +5,7 @@ handler0 (void)
> 
>  void __attribute__ ((interrupt("you load too")))
>  handler1 (void)
> -{ /* { dg-warning "is not \"ilink1\" or \"ilink2\"" } */
> +{ /* { dg-warning "is not \"ilink" } */
>  }
> 
>  void __attribute__ ((interrupt(42)))
> diff --git a/gcc/testsuite/gcc.target/arc/jump-around-jump.c
> b/gcc/testsuite/gcc.target/arc/jump-around-jump.c
> index 338c667..2fd3fb6 100644
> --- a/gcc/testsuite/gcc.target/arc/jump-around-jump.c
> +++ b/gcc/testsuite/gcc.target/arc/jump-around-jump.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-Os -mlock -mswape -mrtsc -fno-reorder-blocks" } */
> +/* { dg-options "-Os -mlock -mswape -fno-reorder-blocks" } */
> 
>  /* This caused an ICE in arc_ifcvt when the 1->3 state change was not
>     implemented for TYPE_UNCOND_BRANCH in arc_ccfsm_post_advance.  */
> diff --git a/gcc/testsuite/gcc.target/arc/mA6.c
> b/gcc/testsuite/gcc.target/arc/mA6.c
> index 2e15a86..c4eeb6f 100644
> --- a/gcc/testsuite/gcc.target/arc/mA6.c
> +++ b/gcc/testsuite/gcc.target/arc/mA6.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mA6" } */
> 
>  /* { dg-final { scan-assembler ".cpu ARC600" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mA7.c
> b/gcc/testsuite/gcc.target/arc/mA7.c
> index c4430f4..a3c6f82 100644
> --- a/gcc/testsuite/gcc.target/arc/mA7.c
> +++ b/gcc/testsuite/gcc.target/arc/mA7.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mA7" } */
> 
>  /* { dg-final { scan-assembler ".cpu ARC700" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mARC600.c
> b/gcc/testsuite/gcc.target/arc/mARC600.c
> index 20e086a..6a80457 100644
> --- a/gcc/testsuite/gcc.target/arc/mARC600.c
> +++ b/gcc/testsuite/gcc.target/arc/mARC600.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mARC600" } */
> 
>  /* { dg-final { scan-assembler ".cpu ARC600" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mARC601.c
> b/gcc/testsuite/gcc.target/arc/mARC601.c
> index 1d30da4..d238661 100644
> --- a/gcc/testsuite/gcc.target/arc/mARC601.c
> +++ b/gcc/testsuite/gcc.target/arc/mARC601.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mARC601" } */
> 
> -/* { dg-final { scan-assembler ".cpu ARC601" } } */
> +/* { dg-final { scan-assembler ".cpu ARC60.*" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mARC700.c
> b/gcc/testsuite/gcc.target/arc/mARC700.c
> index 43e9baa..d34583f 100644
> --- a/gcc/testsuite/gcc.target/arc/mARC700.c
> +++ b/gcc/testsuite/gcc.target/arc/mARC700.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mARC700" } */
> 
>  /* { dg-final { scan-assembler ".cpu ARC700" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
> b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
> index 4c915fd..bd1dc95 100644
> --- a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
> +++ b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-mcpu=ARC600" } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-mcpu=arc600" } */
> 
>  /* { dg-final { scan-assembler ".cpu ARC600" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
> b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
> index 7c93c9d..8ef046e 100644
> --- a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
> +++ b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-mcpu=ARC601" } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-mcpu=arc601" } */
> 
> -/* { dg-final { scan-assembler ".cpu ARC601" } } */
> +/* { dg-final { scan-assembler ".cpu ARC60.*" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
> b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
> index c805a5a..25bb400 100644
> --- a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
> +++ b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-mcpu=ARC700" } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-mcpu=arc700" } */
> 
>  /* { dg-final { scan-assembler ".cpu ARC700" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcrc.c
> b/gcc/testsuite/gcc.target/arc/mcrc.c
> deleted file mode 100644
> index a449bdd..0000000
> --- a/gcc/testsuite/gcc.target/arc/mcrc.c
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -/* { dg-options "-mcrc" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mdpfp.c
> b/gcc/testsuite/gcc.target/arc/mdpfp.c
> index 4bbc905..aa6bdfa 100644
> --- a/gcc/testsuite/gcc.target/arc/mdpfp.c
> +++ b/gcc/testsuite/gcc.target/arc/mdpfp.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */
>  /* { dg-options "-O2 -mdpfp" } */
> 
>  double i;
> diff --git a/gcc/testsuite/gcc.target/arc/mdsp-packa.c
> b/gcc/testsuite/gcc.target/arc/mdsp-packa.c
> deleted file mode 100644
> index f013a6d..0000000
> --- a/gcc/testsuite/gcc.target/arc/mdsp-packa.c
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mdsp-packa" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mdvbf.c
> b/gcc/testsuite/gcc.target/arc/mdvbf.c
> deleted file mode 100644
> index e2e545e..0000000
> --- a/gcc/testsuite/gcc.target/arc/mdvbf.c
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mdvbf" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mmac-24.c
> b/gcc/testsuite/gcc.target/arc/mmac-24.c
> deleted file mode 100644
> index 89da0b1..0000000
> --- a/gcc/testsuite/gcc.target/arc/mmac-24.c
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -/* { dg-options "-mmac-24" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mmac-d16.c
> b/gcc/testsuite/gcc.target/arc/mmac-d16.c
> deleted file mode 100644
> index 0570011..0000000
> --- a/gcc/testsuite/gcc.target/arc/mmac-d16.c
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mmac-d16" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-crc.c
> b/gcc/testsuite/gcc.target/arc/mno-crc.c
> deleted file mode 100644
> index 70ab9c1..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-crc.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-crc" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
> b/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
> deleted file mode 100644
> index eb21522..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-dsp-packa" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-dvbf.c
> b/gcc/testsuite/gcc.target/arc/mno-dvbf.c
> deleted file mode 100644
> index ea96d98..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-dvbf.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-dvbf" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-24.c
> b/gcc/testsuite/gcc.target/arc/mno-mac-24.c
> deleted file mode 100644
> index b483957..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-mac-24.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-mac-24" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c
> b/gcc/testsuite/gcc.target/arc/mno-mac-d16.c
> deleted file mode 100644
> index 68a20f4..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-mac-d16" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-rtsc.c
> b/gcc/testsuite/gcc.target/arc/mno-rtsc.c
> deleted file mode 100644
> index d74a60e..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-rtsc.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-rtsc" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("rtsc %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-xy.c
> b/gcc/testsuite/gcc.target/arc/mno-xy.c
> deleted file mode 100644
> index e378b3f..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-xy.c
> +++ /dev/null
> @@ -1,10 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-xy" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -void f (int i)
> -{
> -  __asm__("add x0_u0, x0_u0, %0" : :  "r" (i));
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c
> b/gcc/testsuite/gcc.target/arc/movb-1.c
> index 65d4ba4..965fd66 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct { unsigned a: 5, b: 8, c: 19; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c
> b/gcc/testsuite/gcc.target/arc/movb-2.c
> index 1ba9976..9bd6d41 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-2.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct { unsigned a: 23, b: 9; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c
> b/gcc/testsuite/gcc.target/arc/movb-3.c
> index 0895154..34145d6 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-3.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-3.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct { int a: 23, b: 9; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c
> b/gcc/testsuite/gcc.target/arc/movb-4.c
> index 89bf2c2..83efad6 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-4.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-4.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct { int a: 13, b: 19; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c
> b/gcc/testsuite/gcc.target/arc/movb-5.c
> index 9dbe8a1..0bcdd1c 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-5.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-5.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct { int a: 23, b: 9; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c
> b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
> index 402250c..977a0c2 100644
> --- a/gcc/testsuite/gcc.target/arc/movb_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  int
> diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c
> b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
> index d2e5a94..4a1484a 100644
> --- a/gcc/testsuite/gcc.target/arc/movb_cl-2.c
> +++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  extern void g (void);
> diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
> b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
> index 3c457db..a86d06f 100644
> --- a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  int
> diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> index 220cd9d..13c0f34 100644
> --- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  struct thing
> diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c
> b/gcc/testsuite/gcc.target/arc/movl-1.c
> index f1f0130..c44ca8d 100644
> --- a/gcc/testsuite/gcc.target/arc/movl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
> 
>  int
> diff --git a/gcc/testsuite/gcc.target/arc/mrtsc.c
> b/gcc/testsuite/gcc.target/arc/mrtsc.c
> deleted file mode 100644
> index 15cb939..0000000
> --- a/gcc/testsuite/gcc.target/arc/mrtsc.c
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -/* { dg-options "-mrtsc" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("rtsc %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mspfp.c
> b/gcc/testsuite/gcc.target/arc/mspfp.c
> index 0e41ff8..19cb978 100644
> --- a/gcc/testsuite/gcc.target/arc/mspfp.c
> +++ b/gcc/testsuite/gcc.target/arc/mspfp.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "FPX is not an ARC HS extension" { archs } } */
>  /* { dg-options "-O2 -mspfp" } */
> 
>  float i;
> diff --git a/gcc/testsuite/gcc.target/arc/mul64.c
> b/gcc/testsuite/gcc.target/arc/mul64.c
> index 3678b27..680dfd8 100644
> --- a/gcc/testsuite/gcc.target/arc/mul64.c
> +++ b/gcc/testsuite/gcc.target/arc/mul64.c
> @@ -1,5 +1,6 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -mcpu=ARC600 -mmul64" } */
> +/* { dg-skip-if "MUL64 is ARC600 extension" { ! { arc6xx } } } */
> +/* { dg-options "-O2 -mcpu=arc600 -mmul64" } */
>  #include <stdint.h>
> 
>  int64_t i;
> diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
> b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
> index 398ecfe..fd48f65 100644
> --- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
> +++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
> @@ -1,5 +1,5 @@
>  /* { dg-do run } */
> -/* { dg-options "-O2 -mARC700 --save-temps" } */
> +/* { dg-options "-O2" } */
> 
>  #include <stdlib.h>
> 
> @@ -25,4 +25,5 @@ main (void)
>    return 0;
>  }
> 
> -/* { dg-final { scan-assembler "mpyhu\[ \t\]" } } */
> +/* { dg-final { scan-assembler "mpyhu\[ \t\]" { target { arc700 } } } } */
> +/* { dg-final { scan-assembler "mpy.u\[ \t\]" { target { { ! { arc700 } } &&
> arcmpy } } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
> b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
> index ccc74e7..287d96d 100644
> --- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
> +++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
> @@ -1,5 +1,7 @@
>  /* { dg-do run } */
> -/* { dg-options "-O2 -mARC700 --save-temps -mno-mpy" } */
> +/* { dg-skip-if "ARC700 always has mpy option on" { arc700 } } */
> +/* { dg-skip-if "ARC600 doesn't have mpy instruction" { arc6xx } } */
> +/* { dg-options "-O2 --save-temps -mmpy-option=0" } */
> 
>  #include <stdlib.h>
> 
> diff --git a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
> b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
> index e4e23e4..61f07b5 100644
> --- a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
> +++ b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */
>  /* { dg-options "-O2 -mdpfp -mno-dpfp-lrsr" } */
> 
>  double i;
> diff --git a/gcc/testsuite/gcc.target/arc/nps400-1.c
> b/gcc/testsuite/gcc.target/arc/nps400-1.c
> index f3d6271..504aad7 100644
> --- a/gcc/testsuite/gcc.target/arc/nps400-1.c
> +++ b/gcc/testsuite/gcc.target/arc/nps400-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mq-class -mbitops -munaligned-access -
> mcmem -O2 -fno-strict-aliasing" } */
> 
>  enum npsdp_mem_space_type {
> diff --git a/gcc/testsuite/gcc.target/arc/trsub.c
> b/gcc/testsuite/gcc.target/arc/trsub.c
> index 031935f..8ea5711 100644
> --- a/gcc/testsuite/gcc.target/arc/trsub.c
> +++ b/gcc/testsuite/gcc.target/arc/trsub.c
> @@ -1,6 +1,7 @@
>  /* Tests if we generate rsub instructions when compiling using
>     floating point assist instructions.  */
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mfpu=fpuda -mcpu=arcem" } */
> 
>  double foo (double a)
> diff --git a/gcc/testsuite/gcc.target/arc/va_args-1.c
> b/gcc/testsuite/gcc.target/arc/va_args-1.c
> new file mode 100644
> index 0000000..4a35d12
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/va_args-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-sources "abitest.S" } */
> +
> +extern long tsyscall (long int sysnum, ...);
> +
> +int main (void)
> +{
> +  long a;
> +
> +  a = tsyscall (1, 2, 3, 4, 5, 6, 7);
> +
> +  if (a != 28)
> +    return 1;
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/arc/va_args-2.c
> b/gcc/testsuite/gcc.target/arc/va_args-2.c
> new file mode 100644
> index 0000000..1a49251
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/va_args-2.c
> @@ -0,0 +1,14 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-sources "abitest.S" } */
> +
> +extern int clone (int (*fn)(void *), void *child_stack,
> +		  int flags, void *arg, ...);
> +
> +int main (void)
> +{
> +  int a = clone ((void *) 1, (void *)2, 3, (void *) 4, 5, 6, 7);
> +  if (a != 28)
> +    return 1;
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/arc/va_args-3.c
> b/gcc/testsuite/gcc.target/arc/va_args-3.c
> new file mode 100644
> index 0000000..45624c1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/va_args-3.c
> @@ -0,0 +1,15 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-sources "abitest.S" } */
> +
> +extern long long abidi (int a, ...);
> +
> +int main (void)
> +{
> +  long long a = 1;
> +  a = abidi (10, a);
> +
> +  if (a != 2)
> +    return 1;
> +  return 0;
> +}
> --
> 1.9.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/2] [ARC] Update target specific tests.
  2016-05-30 14:21 ` [PATCH 2/2] [ARC] Update target specific tests Claudiu Zissulescu
  2016-11-15 15:23   ` Claudiu Zissulescu
@ 2016-11-16 15:58   ` Andrew Burgess
  2016-11-17 13:48     ` Claudiu Zissulescu
  1 sibling, 1 reply; 18+ messages in thread
From: Andrew Burgess @ 2016-11-16 15:58 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: gcc-patches, gnu, Francois.Bedard

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-05-30 14:32:38 +0200]:

> Update the ARC specific tests.
> 
> OK to apply?
> Claudiu
> 
> gcc/
> 2016-05-26  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* testsuite/gcc.target/arc/abitest.S: New file.
> 	* testsuite/gcc.target/arc/va_args-1.c: Likewise.
> 	* testsuite/gcc.target/arc/va_args-2.c: Likewise.
> 	* testsuite/gcc.target/arc/va_args-3.c: Likewise.
> 	* testsuite/gcc.target/arc/mcrc.c: Deleted.
> 	* testsuite/gcc.target/arc/mdsp-packa.c: Likewise.
> 	* testsuite/gcc.target/arc/mdvbf.c: Likewise.
> 	* testsuite/gcc.target/arc/mmac-24.c: Likewise.
> 	* testsuite/gcc.target/arc/mmac-d16.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-crc.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-dsp-packa.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-dvbf.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-mac-24.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-mac-d16.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-rtsc.c: Likewise.
> 	* testsuite/gcc.target/arc/mno-xy.c: Likewise.
> 	* testsuite/gcc.target/arc/mrtsc.c: Likewise.
> 	* testsuite/gcc.target/arc/arc.exp (check_effective_target_arcem):
> 	New function.
> 	(check_effective_target_arc700): Likewise.
> 	(check_effective_target_arc6xx): Likewise.
> 	(check_effective_target_arcmpy): Likewise.
> 	(check_effective_target_archs): Likewise.
> 	(check_effective_target_clmcpu): Likewise.
> 	* testsuite/gcc.target/arc/barrel-shifter-1.c: Changed.
> 	* testsuite/gcc.target/arc/builtin_simd.c: Test only for ARC700
> 	cpus.
> 	* testsuite/gcc.target/arc/cmem-1.c: Changed.
> 	* testsuite/gcc.target/arc/cmem-2.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-3.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-4.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-5.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-6.c: Likewise.
> 	* testsuite/gcc.target/arc/cmem-7.c: Likewise.
> 	* testsuite/gcc.target/arc/interrupt-1.c: Test for RTIE as well.
> 	* testsuite/gcc.target/arc/interrupt-2.c: Skip it for ARCv2 cores.
> 	* testsuite/gcc.target/arc/interrupt-3.c: Match also ARCv2
> 	warnings.
> 	* testsuite/gcc.target/arc/jump-around-jump.c: Update options.
> 	* testsuite/gcc.target/arc/mARC601.c: Changed.
> 	* testsuite/gcc.target/arc/mcpu-arc600.c: Changed.
> 	* testsuite/gcc.target/arc/mcpu-arc601.c: Changed.
> 	* testsuite/gcc.target/arc/mcpu-arc700.c: Changed.
> 	* testsuite/gcc.target/arc/mdpfp.c: Skip for ARCv2 cores.
> 	* testsuite/gcc.target/arc/movb-1.c: Changed.
> 	* testsuite/gcc.target/arc/movb-2.c: Likewise.
> 	* testsuite/gcc.target/arc/movb-3.c: Likewise.
> 	* testsuite/gcc.target/arc/movb-4.c: Likewise.
> 	* testsuite/gcc.target/arc/movb-5.c: Likewise.
> 	* testsuite/gcc.target/arc/movb_cl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/movb_cl-2.c: Likewise.
> 	* testsuite/gcc.target/arc/movbi_cl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/movh_cl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/mspfp.c: Skip for ARC HS cores.
> 	* testsuite/gcc.target/arc/mul64.c: Enable it only for ARC600.
> 	* testsuite/gcc.target/arc/mulsi3_highpart-1.c: Scan for ARCv2
> 	instructions.
> 	* testsuite/gcc.target/arc/mulsi3_highpart-2.c: Skip it for ARCv1
> 	cores.
> 	* testsuite/gcc.target/arc/no-dpfp-lrsr.c: Skip it for ARC HS.
> 	* testsuite/gcc.target/arc/trsub.c: Only for ARC EM cores.
> 	* testsuite/gcc.target/arc/builtin_simdarc.c: Changed.
> 	* testsuite/gcc.target/arc/extzv-1.c: Likewise.
> 	* testsuite/gcc.target/arc/insv-1.c: Likewise.
> 	* testsuite/gcc.target/arc/insv-2.c: Likewise.
> 	* testsuite/gcc.target/arc/mA6.c: Likewise.
> 	* testsuite/gcc.target/arc/mA7.c: Likewise.
> 	* testsuite/gcc.target/arc/mARC600.c: Likewise.
> 	* testsuite/gcc.target/arc/mARC700.c: Likewise.
> 	* testsuite/gcc.target/arc/mcpu-arc600.c: Likewise.
> 	* testsuite/gcc.target/arc/mcpu-arc700.c: Likewise.
> 	* testsuite/gcc.target/arc/movl-1.c: Likewise.
> 	* testsuite/gcc.target/arc/nps400-1.c: Likewise.
> 	* testsuite/gcc.target/arc/trsub.c: Likewise.


These entries should be going into the gcc/testsuite/ChangeLog file,
and so don't need the "testsuite/" prefix.

Otherwise I'm happy for this to be merged.  I've only skimmed the
change, but assuming you've run the tests this all seems good.

Thanks,
Andrew



> ---
>  gcc/testsuite/gcc.target/arc/abitest.S           | 31 +++++++++++
>  gcc/testsuite/gcc.target/arc/arc.exp             | 66 +++++++++++++++++++++++-
>  gcc/testsuite/gcc.target/arc/barrel-shifter-1.c  |  2 +-
>  gcc/testsuite/gcc.target/arc/builtin_simd.c      |  1 +
>  gcc/testsuite/gcc.target/arc/builtin_simdarc.c   |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-2.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-3.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-4.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-5.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-6.c            |  1 +
>  gcc/testsuite/gcc.target/arc/cmem-7.c            |  1 +
>  gcc/testsuite/gcc.target/arc/extzv-1.c           |  1 +
>  gcc/testsuite/gcc.target/arc/insv-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/insv-2.c            |  1 +
>  gcc/testsuite/gcc.target/arc/interrupt-1.c       |  7 ++-
>  gcc/testsuite/gcc.target/arc/interrupt-2.c       |  1 +
>  gcc/testsuite/gcc.target/arc/interrupt-3.c       |  2 +-
>  gcc/testsuite/gcc.target/arc/jump-around-jump.c  |  2 +-
>  gcc/testsuite/gcc.target/arc/mA6.c               |  1 +
>  gcc/testsuite/gcc.target/arc/mA7.c               |  1 +
>  gcc/testsuite/gcc.target/arc/mARC600.c           |  1 +
>  gcc/testsuite/gcc.target/arc/mARC601.c           |  3 +-
>  gcc/testsuite/gcc.target/arc/mARC700.c           |  1 +
>  gcc/testsuite/gcc.target/arc/mcpu-arc600.c       |  3 +-
>  gcc/testsuite/gcc.target/arc/mcpu-arc601.c       |  5 +-
>  gcc/testsuite/gcc.target/arc/mcpu-arc700.c       |  3 +-
>  gcc/testsuite/gcc.target/arc/mcrc.c              |  8 ---
>  gcc/testsuite/gcc.target/arc/mdpfp.c             |  1 +
>  gcc/testsuite/gcc.target/arc/mdsp-packa.c        |  9 ----
>  gcc/testsuite/gcc.target/arc/mdvbf.c             |  9 ----
>  gcc/testsuite/gcc.target/arc/mmac-24.c           |  8 ---
>  gcc/testsuite/gcc.target/arc/mmac-d16.c          |  9 ----
>  gcc/testsuite/gcc.target/arc/mno-crc.c           | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-dsp-packa.c     | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-dvbf.c          | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-mac-24.c        | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-mac-d16.c       | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-rtsc.c          | 11 ----
>  gcc/testsuite/gcc.target/arc/mno-xy.c            | 10 ----
>  gcc/testsuite/gcc.target/arc/movb-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-2.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-3.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-4.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb-5.c            |  1 +
>  gcc/testsuite/gcc.target/arc/movb_cl-1.c         |  1 +
>  gcc/testsuite/gcc.target/arc/movb_cl-2.c         |  1 +
>  gcc/testsuite/gcc.target/arc/movbi_cl-1.c        |  1 +
>  gcc/testsuite/gcc.target/arc/movh_cl-1.c         |  1 +
>  gcc/testsuite/gcc.target/arc/movl-1.c            |  1 +
>  gcc/testsuite/gcc.target/arc/mrtsc.c             |  8 ---
>  gcc/testsuite/gcc.target/arc/mspfp.c             |  1 +
>  gcc/testsuite/gcc.target/arc/mul64.c             |  3 +-
>  gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c |  5 +-
>  gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c |  4 +-
>  gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c      |  1 +
>  gcc/testsuite/gcc.target/arc/nps400-1.c          |  1 +
>  gcc/testsuite/gcc.target/arc/trsub.c             |  1 +
>  gcc/testsuite/gcc.target/arc/va_args-1.c         | 16 ++++++
>  gcc/testsuite/gcc.target/arc/va_args-2.c         | 14 +++++
>  gcc/testsuite/gcc.target/arc/va_args-3.c         | 15 ++++++
>  61 files changed, 198 insertions(+), 142 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/abitest.S
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mcrc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mdsp-packa.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mdvbf.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-24.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-d16.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-crc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dvbf.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-24.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-d16.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-rtsc.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mno-xy.c
>  delete mode 100644 gcc/testsuite/gcc.target/arc/mrtsc.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-1.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-2.c
>  create mode 100644 gcc/testsuite/gcc.target/arc/va_args-3.c
> 
> diff --git a/gcc/testsuite/gcc.target/arc/abitest.S b/gcc/testsuite/gcc.target/arc/abitest.S
> new file mode 100644
> index 0000000..7be935b
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/abitest.S
> @@ -0,0 +1,31 @@
> +/* { dg-do assemble } */
> +#ifndef ENTRY
> +#define ENTRY(nm)               \
> +        .text `                 \
> +        .align 4 `              \
> +        .globl nm `             \
> +        .type nm,@function `    \
> +nm:
> +#endif
> +
> +#ifndef END
> +#define END(name)       .size name,.-name
> +#endif
> +
> +ENTRY(tsyscall)
> +ENTRY(clone)
> +	add	r0,r0,r1
> +	add	r0,r0,r2
> +	add	r0,r0,r3
> +	add	r0,r0,r4
> +	add	r0,r0,r5
> +	j_s.d	[blink]
> +	add	r0,r0,r6
> +END(tsyscall)
> +END(clone)
> +
> +ENTRY(abidi)
> +	add.f r0,r1,1
> +        j_s.d [blink]
> +        adc r1,r2,0
> +END(abidi)
> diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp
> index fae2ece7..3b7d100 100644
> --- a/gcc/testsuite/gcc.target/arc/arc.exp
> +++ b/gcc/testsuite/gcc.target/arc/arc.exp
> @@ -4,12 +4,12 @@
>  # it under the terms of the GNU General Public License as published by
>  # the Free Software Foundation; either version 3 of the License, or
>  # (at your option) any later version.
> -# 
> +#
>  # This program is distributed in the hope that it will be useful,
>  # but WITHOUT ANY WARRANTY; without even the implied warranty of
>  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>  # GNU General Public License for more details.
> -# 
> +#
>  # You should have received a copy of the GNU General Public License
>  # along with GCC; see the file COPYING3.  If not see
>  # <http://www.gnu.org/licenses/>.
> @@ -24,6 +24,68 @@ if ![istarget arc*-*-*] then {
>  # Load support procs.
>  load_lib gcc-dg.exp
>  
> +# Return 1 if this is a compiler supporting ARCv2 EM as default processor
> +proc check_effective_target_arcem { } {
> +    return [check_no_compiler_messages arcem assembly {
> +	#if !defined (__ARCEM__)
> +	#error No ARC EM
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if we compile for ARC700
> +proc check_effective_target_arc700 { } {
> +    return [check_no_compiler_messages arc700 assembly {
> +	#if !defined (__ARC700__)
> +	#error No ARC 700
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if we compile for ARC6xx
> +proc check_effective_target_arc6xx { } {
> +    return [check_no_compiler_messages arc6xx assembly {
> +	#if !defined (__ARC600__) && !defined (__ARC601__)
> +	#error No ARC 6xx
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if we have mpy
> +proc check_effective_target_arcmpy { } {
> +    return [check_no_compiler_messages arcmpy assembly {
> +	#if !defined (__ARC_MPY__)
> +	#error No MPY
> +	#endif
> +    }]
> +}
> +
> +# Return 1 if this is a compiler supporting ARC HS as default processor
> +proc check_effective_target_archs { } {
> +    return [check_no_compiler_messages archs assembly {
> +	#if !defined (__ARCHS__)
> +	#error No ARC HS
> +	#endif
> +    }]
> +}
> +
> +proc check_cl { flags } {
> +    return [check_no_compiler_messages check_$flags assembly {
> +	#if !defined (__arc__)
> +	#error Extra mcpu options
> +	#endif
> +    } "$flags"]
> +}
> +
> +# Return 1 if there are no extra mcpu options given via command line
> +proc check_effective_target_clmcpu { } {
> +    if { [check_cl "-mcpu=arc700"]
> +	 && [check_cl "-mcpu=arcem" ] } {
> +	return 1
> +    }
> +    return 0
> +}
> +
>  # If a testcase doesn't have special options, use these.
>  global DEFAULT_CFLAGS
>  if ![info exists DEFAULT_CFLAGS] then {
> diff --git a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
> index a0eb6d7..5cfb282 100644
> --- a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
> +++ b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -mcpu=ARC601 -mbarrel-shifter" } */
> +/* { dg-options "-O2 -mbarrel-shifter" } */
>  int i;
>  
>  int f (void)
> diff --git a/gcc/testsuite/gcc.target/arc/builtin_simd.c b/gcc/testsuite/gcc.target/arc/builtin_simd.c
> index fff27a4..6b02521 100644
> --- a/gcc/testsuite/gcc.target/arc/builtin_simd.c
> +++ b/gcc/testsuite/gcc.target/arc/builtin_simd.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-O2 -Werror-implicit-function-declaration -mARC700 -msimd" } */
>  
>  #define STEST1(name, rettype, op1)		\
> diff --git a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
> index 68aae40..0cfe2ad 100644
> --- a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
> +++ b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=archs -O2 -Werror-implicit-function-declaration -mmpy-option=9" } */
>  
>  #define STEST(name, rettype, op1type, op2type)	\
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c b/gcc/testsuite/gcc.target/arc/cmem-1.c
> index 7f36afb..8ed5dcf 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-1.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
>  
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c b/gcc/testsuite/gcc.target/arc/cmem-2.c
> index a3d7c130..39bfb28 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-2.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
>  
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c b/gcc/testsuite/gcc.target/arc/cmem-3.c
> index dee73b5..109084f 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-3.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-3.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
>  
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c b/gcc/testsuite/gcc.target/arc/cmem-4.c
> index 1da6bce..4ac8a22 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-4.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-4.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
>  
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c b/gcc/testsuite/gcc.target/arc/cmem-5.c
> index ad6904f..451218b 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-5.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-5.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
>  
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c b/gcc/testsuite/gcc.target/arc/cmem-6.c
> index 24bc39b..0ed0608 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-6.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-6.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
>  
>  #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
> diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c b/gcc/testsuite/gcc.target/arc/cmem-7.c
> index 72ee7bd..0267327 100644
> --- a/gcc/testsuite/gcc.target/arc/cmem-7.c
> +++ b/gcc/testsuite/gcc.target/arc/cmem-7.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mcmem" } */
>  
>  struct some_struct
> diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c b/gcc/testsuite/gcc.target/arc/extzv-1.c
> index 242f522..1e5533a7 100644
> --- a/gcc/testsuite/gcc.target/arc/extzv-1.c
> +++ b/gcc/testsuite/gcc.target/arc/extzv-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct foo { unsigned a: 3, b: 5, c: 24; };
> diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c b/gcc/testsuite/gcc.target/arc/insv-1.c
> index 75d47e9..29e4188 100644
> --- a/gcc/testsuite/gcc.target/arc/insv-1.c
> +++ b/gcc/testsuite/gcc.target/arc/insv-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  /* ??? Irrespective of insn set, generated code for this is a mess.  */
> diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c b/gcc/testsuite/gcc.target/arc/insv-2.c
> index 1652551..620acec 100644
> --- a/gcc/testsuite/gcc.target/arc/insv-2.c
> +++ b/gcc/testsuite/gcc.target/arc/insv-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct foo { unsigned a: 3, b: 8, c: 21; } bar;
> diff --git a/gcc/testsuite/gcc.target/arc/interrupt-1.c b/gcc/testsuite/gcc.target/arc/interrupt-1.c
> index 7051457..8a2002b 100644
> --- a/gcc/testsuite/gcc.target/arc/interrupt-1.c
> +++ b/gcc/testsuite/gcc.target/arc/interrupt-1.c
> @@ -1,5 +1,10 @@
> +#if defined (__ARCHS__) || defined (__ARCEM__)
> +void __attribute__ ((interrupt("ilink")))
> +#else
>  void __attribute__ ((interrupt("ilink1")))
> +#endif
>  handler1 (void)
>  {
>  }
> -/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 } } */
> +/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 { target { arc700 || arc6xx } } } } */
> +/* { dg-final { scan-assembler-times "rtie" 1 { target { arcem || archs } } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/interrupt-2.c b/gcc/testsuite/gcc.target/arc/interrupt-2.c
> index ee8593b..285ebd5 100644
> --- a/gcc/testsuite/gcc.target/arc/interrupt-2.c
> +++ b/gcc/testsuite/gcc.target/arc/interrupt-2.c
> @@ -1,3 +1,4 @@
> +/* { dg-skip-if "ilink2 is not an ARCv2 register" { archs || arcem } } */
>  void __attribute__ ((interrupt("ilink2")))
>  handler1 (void)
>  {
> diff --git a/gcc/testsuite/gcc.target/arc/interrupt-3.c b/gcc/testsuite/gcc.target/arc/interrupt-3.c
> index fa598d6..b0cad88 100644
> --- a/gcc/testsuite/gcc.target/arc/interrupt-3.c
> +++ b/gcc/testsuite/gcc.target/arc/interrupt-3.c
> @@ -5,7 +5,7 @@ handler0 (void)
>  
>  void __attribute__ ((interrupt("you load too")))
>  handler1 (void)
> -{ /* { dg-warning "is not \"ilink1\" or \"ilink2\"" } */
> +{ /* { dg-warning "is not \"ilink" } */
>  }
>  
>  void __attribute__ ((interrupt(42)))
> diff --git a/gcc/testsuite/gcc.target/arc/jump-around-jump.c b/gcc/testsuite/gcc.target/arc/jump-around-jump.c
> index 338c667..2fd3fb6 100644
> --- a/gcc/testsuite/gcc.target/arc/jump-around-jump.c
> +++ b/gcc/testsuite/gcc.target/arc/jump-around-jump.c
> @@ -1,5 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-Os -mlock -mswape -mrtsc -fno-reorder-blocks" } */
> +/* { dg-options "-Os -mlock -mswape -fno-reorder-blocks" } */
>  
>  /* This caused an ICE in arc_ifcvt when the 1->3 state change was not
>     implemented for TYPE_UNCOND_BRANCH in arc_ccfsm_post_advance.  */
> diff --git a/gcc/testsuite/gcc.target/arc/mA6.c b/gcc/testsuite/gcc.target/arc/mA6.c
> index 2e15a86..c4eeb6f 100644
> --- a/gcc/testsuite/gcc.target/arc/mA6.c
> +++ b/gcc/testsuite/gcc.target/arc/mA6.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mA6" } */
>  
>  /* { dg-final { scan-assembler ".cpu ARC600" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mA7.c b/gcc/testsuite/gcc.target/arc/mA7.c
> index c4430f4..a3c6f82 100644
> --- a/gcc/testsuite/gcc.target/arc/mA7.c
> +++ b/gcc/testsuite/gcc.target/arc/mA7.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mA7" } */
>  
>  /* { dg-final { scan-assembler ".cpu ARC700" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mARC600.c b/gcc/testsuite/gcc.target/arc/mARC600.c
> index 20e086a..6a80457 100644
> --- a/gcc/testsuite/gcc.target/arc/mARC600.c
> +++ b/gcc/testsuite/gcc.target/arc/mARC600.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mARC600" } */
>  
>  /* { dg-final { scan-assembler ".cpu ARC600" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mARC601.c b/gcc/testsuite/gcc.target/arc/mARC601.c
> index 1d30da4..d238661 100644
> --- a/gcc/testsuite/gcc.target/arc/mARC601.c
> +++ b/gcc/testsuite/gcc.target/arc/mARC601.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mARC601" } */
>  
> -/* { dg-final { scan-assembler ".cpu ARC601" } } */
> +/* { dg-final { scan-assembler ".cpu ARC60.*" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mARC700.c b/gcc/testsuite/gcc.target/arc/mARC700.c
> index 43e9baa..d34583f 100644
> --- a/gcc/testsuite/gcc.target/arc/mARC700.c
> +++ b/gcc/testsuite/gcc.target/arc/mARC700.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mARC700" } */
>  
>  /* { dg-final { scan-assembler ".cpu ARC700" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
> index 4c915fd..bd1dc95 100644
> --- a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
> +++ b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-mcpu=ARC600" } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-mcpu=arc600" } */
>  
>  /* { dg-final { scan-assembler ".cpu ARC600" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
> index 7c93c9d..8ef046e 100644
> --- a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
> +++ b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-mcpu=ARC601" } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-mcpu=arc601" } */
>  
> -/* { dg-final { scan-assembler ".cpu ARC601" } } */
> +/* { dg-final { scan-assembler ".cpu ARC60.*" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
> index c805a5a..25bb400 100644
> --- a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
> +++ b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> -/* { dg-options "-mcpu=ARC700" } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
> +/* { dg-options "-mcpu=arc700" } */
>  
>  /* { dg-final { scan-assembler ".cpu ARC700" } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mcrc.c b/gcc/testsuite/gcc.target/arc/mcrc.c
> deleted file mode 100644
> index a449bdd..0000000
> --- a/gcc/testsuite/gcc.target/arc/mcrc.c
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -/* { dg-options "-mcrc" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mdpfp.c b/gcc/testsuite/gcc.target/arc/mdpfp.c
> index 4bbc905..aa6bdfa 100644
> --- a/gcc/testsuite/gcc.target/arc/mdpfp.c
> +++ b/gcc/testsuite/gcc.target/arc/mdpfp.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */
>  /* { dg-options "-O2 -mdpfp" } */
>  
>  double i;
> diff --git a/gcc/testsuite/gcc.target/arc/mdsp-packa.c b/gcc/testsuite/gcc.target/arc/mdsp-packa.c
> deleted file mode 100644
> index f013a6d..0000000
> --- a/gcc/testsuite/gcc.target/arc/mdsp-packa.c
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mdsp-packa" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mdvbf.c b/gcc/testsuite/gcc.target/arc/mdvbf.c
> deleted file mode 100644
> index e2e545e..0000000
> --- a/gcc/testsuite/gcc.target/arc/mdvbf.c
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mdvbf" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mmac-24.c b/gcc/testsuite/gcc.target/arc/mmac-24.c
> deleted file mode 100644
> index 89da0b1..0000000
> --- a/gcc/testsuite/gcc.target/arc/mmac-24.c
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -/* { dg-options "-mmac-24" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mmac-d16.c b/gcc/testsuite/gcc.target/arc/mmac-d16.c
> deleted file mode 100644
> index 0570011..0000000
> --- a/gcc/testsuite/gcc.target/arc/mmac-d16.c
> +++ /dev/null
> @@ -1,9 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mmac-d16" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-crc.c b/gcc/testsuite/gcc.target/arc/mno-crc.c
> deleted file mode 100644
> index 70ab9c1..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-crc.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-crc" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c b/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
> deleted file mode 100644
> index eb21522..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-dsp-packa" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-dvbf.c b/gcc/testsuite/gcc.target/arc/mno-dvbf.c
> deleted file mode 100644
> index ea96d98..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-dvbf.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-dvbf" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-24.c b/gcc/testsuite/gcc.target/arc/mno-mac-24.c
> deleted file mode 100644
> index b483957..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-mac-24.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-mac-24" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c b/gcc/testsuite/gcc.target/arc/mno-mac-d16.c
> deleted file mode 100644
> index 68a20f4..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-mac-d16" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-rtsc.c b/gcc/testsuite/gcc.target/arc/mno-rtsc.c
> deleted file mode 100644
> index d74a60e..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-rtsc.c
> +++ /dev/null
> @@ -1,11 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-rtsc" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -int f (int i)
> -{
> -  __asm__("rtsc %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mno-xy.c b/gcc/testsuite/gcc.target/arc/mno-xy.c
> deleted file mode 100644
> index e378b3f..0000000
> --- a/gcc/testsuite/gcc.target/arc/mno-xy.c
> +++ /dev/null
> @@ -1,10 +0,0 @@
> -/* { dg-do compile } */
> -/* { dg-options "-mno-xy" } */
> -/* Would also like to assemble and check that we get the expected
> -   "Error: bad instruction" assembler messages, but at the moment our
> -   testharness can't do that.  */
> -
> -void f (int i)
> -{
> -  __asm__("add x0_u0, x0_u0, %0" : :  "r" (i));
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
> index 65d4ba4..965fd66 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct { unsigned a: 5, b: 8, c: 19; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
> index 1ba9976..9bd6d41 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-2.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct { unsigned a: 23, b: 9; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c b/gcc/testsuite/gcc.target/arc/movb-3.c
> index 0895154..34145d6 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-3.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-3.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct { int a: 23, b: 9; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c b/gcc/testsuite/gcc.target/arc/movb-4.c
> index 89bf2c2..83efad6 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-4.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-4.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct { int a: 13, b: 19; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
> index 9dbe8a1..0bcdd1c 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-5.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-5.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct { int a: 23, b: 9; } foo;
> diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
> index 402250c..977a0c2 100644
> --- a/gcc/testsuite/gcc.target/arc/movb_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  int
> diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
> index d2e5a94..4a1484a 100644
> --- a/gcc/testsuite/gcc.target/arc/movb_cl-2.c
> +++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  extern void g (void);
> diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
> index 3c457db..a86d06f 100644
> --- a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  int
> diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> index 220cd9d..13c0f34 100644
> --- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  struct thing
> diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c b/gcc/testsuite/gcc.target/arc/movl-1.c
> index f1f0130..c44ca8d 100644
> --- a/gcc/testsuite/gcc.target/arc/movl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movl-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
>  
>  int
> diff --git a/gcc/testsuite/gcc.target/arc/mrtsc.c b/gcc/testsuite/gcc.target/arc/mrtsc.c
> deleted file mode 100644
> index 15cb939..0000000
> --- a/gcc/testsuite/gcc.target/arc/mrtsc.c
> +++ /dev/null
> @@ -1,8 +0,0 @@
> -/* { dg-options "-mrtsc" } */
> -/* { dg-do assemble } */
> -
> -int f (int i)
> -{
> -  __asm__("rtsc %1, %1" : "=r"(i) : "r"(i));
> -  return i;
> -}
> diff --git a/gcc/testsuite/gcc.target/arc/mspfp.c b/gcc/testsuite/gcc.target/arc/mspfp.c
> index 0e41ff8..19cb978 100644
> --- a/gcc/testsuite/gcc.target/arc/mspfp.c
> +++ b/gcc/testsuite/gcc.target/arc/mspfp.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "FPX is not an ARC HS extension" { archs } } */
>  /* { dg-options "-O2 -mspfp" } */
>  
>  float i;
> diff --git a/gcc/testsuite/gcc.target/arc/mul64.c b/gcc/testsuite/gcc.target/arc/mul64.c
> index 3678b27..680dfd8 100644
> --- a/gcc/testsuite/gcc.target/arc/mul64.c
> +++ b/gcc/testsuite/gcc.target/arc/mul64.c
> @@ -1,5 +1,6 @@
>  /* { dg-do compile } */
> -/* { dg-options "-O2 -mcpu=ARC600 -mmul64" } */
> +/* { dg-skip-if "MUL64 is ARC600 extension" { ! { arc6xx } } } */
> +/* { dg-options "-O2 -mcpu=arc600 -mmul64" } */
>  #include <stdint.h>
>  
>  int64_t i;
> diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
> index 398ecfe..fd48f65 100644
> --- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
> +++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
> @@ -1,5 +1,5 @@
>  /* { dg-do run } */
> -/* { dg-options "-O2 -mARC700 --save-temps" } */
> +/* { dg-options "-O2" } */
>  
>  #include <stdlib.h>
>  
> @@ -25,4 +25,5 @@ main (void)
>    return 0;
>  }
>  
> -/* { dg-final { scan-assembler "mpyhu\[ \t\]" } } */
> +/* { dg-final { scan-assembler "mpyhu\[ \t\]" { target { arc700 } } } } */
> +/* { dg-final { scan-assembler "mpy.u\[ \t\]" { target { { ! { arc700 } } && arcmpy } } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
> index ccc74e7..287d96d 100644
> --- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
> +++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
> @@ -1,5 +1,7 @@
>  /* { dg-do run } */
> -/* { dg-options "-O2 -mARC700 --save-temps -mno-mpy" } */
> +/* { dg-skip-if "ARC700 always has mpy option on" { arc700 } } */
> +/* { dg-skip-if "ARC600 doesn't have mpy instruction" { arc6xx } } */
> +/* { dg-options "-O2 --save-temps -mmpy-option=0" } */
>  
>  #include <stdlib.h>
>  
> diff --git a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
> index e4e23e4..61f07b5 100644
> --- a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
> +++ b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */
>  /* { dg-options "-O2 -mdpfp -mno-dpfp-lrsr" } */
>  
>  double i;
> diff --git a/gcc/testsuite/gcc.target/arc/nps400-1.c b/gcc/testsuite/gcc.target/arc/nps400-1.c
> index f3d6271..504aad7 100644
> --- a/gcc/testsuite/gcc.target/arc/nps400-1.c
> +++ b/gcc/testsuite/gcc.target/arc/nps400-1.c
> @@ -1,4 +1,5 @@
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mcpu=nps400 -mq-class -mbitops -munaligned-access -mcmem -O2 -fno-strict-aliasing" } */
>  
>  enum npsdp_mem_space_type {
> diff --git a/gcc/testsuite/gcc.target/arc/trsub.c b/gcc/testsuite/gcc.target/arc/trsub.c
> index 031935f..8ea5711 100644
> --- a/gcc/testsuite/gcc.target/arc/trsub.c
> +++ b/gcc/testsuite/gcc.target/arc/trsub.c
> @@ -1,6 +1,7 @@
>  /* Tests if we generate rsub instructions when compiling using
>     floating point assist instructions.  */
>  /* { dg-do compile } */
> +/* { dg-skip-if "" { ! { clmcpu } } } */
>  /* { dg-options "-mfpu=fpuda -mcpu=arcem" } */
>  
>  double foo (double a)
> diff --git a/gcc/testsuite/gcc.target/arc/va_args-1.c b/gcc/testsuite/gcc.target/arc/va_args-1.c
> new file mode 100644
> index 0000000..4a35d12
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/va_args-1.c
> @@ -0,0 +1,16 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-sources "abitest.S" } */
> +
> +extern long tsyscall (long int sysnum, ...);
> +
> +int main (void)
> +{
> +  long a;
> +
> +  a = tsyscall (1, 2, 3, 4, 5, 6, 7);
> +
> +  if (a != 28)
> +    return 1;
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/arc/va_args-2.c b/gcc/testsuite/gcc.target/arc/va_args-2.c
> new file mode 100644
> index 0000000..1a49251
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/va_args-2.c
> @@ -0,0 +1,14 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-sources "abitest.S" } */
> +
> +extern int clone (int (*fn)(void *), void *child_stack,
> +		  int flags, void *arg, ...);
> +
> +int main (void)
> +{
> +  int a = clone ((void *) 1, (void *)2, 3, (void *) 4, 5, 6, 7);
> +  if (a != 28)
> +    return 1;
> +  return 0;
> +}
> diff --git a/gcc/testsuite/gcc.target/arc/va_args-3.c b/gcc/testsuite/gcc.target/arc/va_args-3.c
> new file mode 100644
> index 0000000..45624c1
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/va_args-3.c
> @@ -0,0 +1,15 @@
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +/* { dg-additional-sources "abitest.S" } */
> +
> +extern long long abidi (int a, ...);
> +
> +int main (void)
> +{
> +  long long a = 1;
> +  a = abidi (10, a);
> +
> +  if (a != 2)
> +    return 1;
> +  return 0;
> +}
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 2/2] [ARC] Update target specific tests.
  2016-11-16 15:58   ` Andrew Burgess
@ 2016-11-17 13:48     ` Claudiu Zissulescu
  0 siblings, 0 replies; 18+ messages in thread
From: Claudiu Zissulescu @ 2016-11-17 13:48 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, gnu, Francois.Bedard

> These entries should be going into the gcc/testsuite/ChangeLog file,
> and so don't need the "testsuite/" prefix.
> 
Ups :) Fix it.

> Otherwise I'm happy for this to be merged.  I've only skimmed the
> change, but assuming you've run the tests this all seems good.

Results of running arc.exp on LE/arc700 default cpu should be:

                === gcc Summary ===

# of expected passes            151
# of unsupported tests          2

Committed, thank you for your review,
Claudiu

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2016-11-17 13:48 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-30 14:07 [PATCH 0/2] [ARC] Refurbish backend options Claudiu Zissulescu
2016-05-30 14:19 ` [PATCH 1/2] [ARC] New option handling, refurbish multilib support Claudiu Zissulescu
2016-10-10 13:28   ` [PATCH] " Claudiu Zissulescu
2016-10-12 20:02     ` Andrew Burgess
2016-10-13  8:42       ` Claudiu Zissulescu
2016-10-31 15:48       ` Claudiu Zissulescu
2016-11-03 22:59         ` Andrew Burgess
2016-11-04 11:40           ` Claudiu Zissulescu
2016-11-10 11:04           ` Claudiu Zissulescu
2016-11-14 10:33             ` Andrew Burgess
2016-11-14 10:37               ` Claudiu Zissulescu
2016-11-15  9:37               ` Claudiu Zissulescu
     [not found]                 ` <20161115123637.GB5975@embecosm.com>
2016-11-15 15:11                   ` Claudiu Zissulescu
2016-05-30 14:21 ` [PATCH 2/2] [ARC] Update target specific tests Claudiu Zissulescu
2016-11-15 15:23   ` Claudiu Zissulescu
2016-11-16 15:58   ` Andrew Burgess
2016-11-17 13:48     ` Claudiu Zissulescu
2016-06-15  7:06 ` [PATCH 0/2] [ARC] Refurbish backend options Claudiu Zissulescu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).