public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 01/10] gcc: Add support for mellanox nps400 arc variant
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
@ 2016-03-04 13:25 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 04/10] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns Andrew Burgess
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

This commit adds support for the mellanox nps400 arc variant.  Nothing
much actually changes with this commit other than adding support for
'arc*-mellanox-*' targets at configuration time.

I've added a new makefile fragment for the mellanox variant, right now
there's not much in here, I'll be adding some content in a later commit,
but adding the file now lets me get all of the build
infrastructure (config.gcc) changes done in a single commit.

gcc/ChangeLog:

	* config.gcc: Add support for arc*-mellanox-* nps400 targets.
	* config/arc/t-nps400: New file.
---
 gcc/ChangeLog.NPS400    |  5 +++++
 gcc/config.gcc          | 10 ++++++++++
 gcc/config/arc/t-nps400 | 21 +++++++++++++++++++++
 3 files changed, 36 insertions(+)
 create mode 100644 gcc/config/arc/t-nps400

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 4e68491..286f2dd 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,8 @@
+2016-02-01  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * config.gcc: Add support for arc*-mellanox-* nps400 targets.
+       * config/arc/t-nps400: New file.
+
 2016-02-02  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* common.opt (ffat-lto-objects): Make this flag default on.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 6722260..9a48dca 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1015,6 +1015,11 @@ arc*-*-elf*)
 	case ${with_endian} in
 	big*)	tm_defines="DRIVER_ENDIAN_SELF_SPECS=\\\"%{!EL:%{!mlittle-endian:-mbig-endian}}\\\" ${tm_defines}"
 	esac
+	case ${target} in
+	arc*-mellanox-*)
+		tm_defines="${tm_defines} ARC_NPS400=1"
+		tmake_file="${tmake_file} arc/t-nps400";;
+	esac
 	;;
 arc*-*-linux-uclibc*)
 	extra_headers="arc-simd.h"
@@ -1040,6 +1045,11 @@ arc*-*-linux-uclibc*)
 	case ${with_endian} in
 	big*)	tm_defines="DRIVER_ENDIAN_SELF_SPECS=\\\"%{!EL:%{!mlittle-endian:-mbig-endian}}\\\" ${tm_defines}"
 	esac
+	case ${target} in
+	arc*-mellanox-*)
+		tm_defines="${tm_defines} ARC_NPS400=1"
+		tmake_file="${tmake_file} arc/t-nps400";;
+	esac
         ;;
 arm-wrs-vxworks)
 	tm_file="elfos.h arm/elf.h arm/aout.h ${tm_file} vx-common.h vxworks.h arm/vxworks.h"
diff --git a/gcc/config/arc/t-nps400 b/gcc/config/arc/t-nps400
new file mode 100644
index 0000000..e332e24
--- /dev/null
+++ b/gcc/config/arc/t-nps400
@@ -0,0 +1,21 @@
+# GCC Makefile fragment for Mellanox NPS400 variant of Synopsys
+# DesignWare ARC
+
+# 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=
-- 
2.6.4

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

* [PATCH 00/10] ARC: Add support for NPS400 variant
@ 2016-03-04 13:25 Andrew Burgess
  2016-03-04 13:25 ` [PATCH 01/10] gcc: Add support for mellanox nps400 arc variant Andrew Burgess
                   ` (17 more replies)
  0 siblings, 18 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:25 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

The NPS400 is an ARC700 variant from Mellanox (formally EZChip).

This patch series adds a new GCC build target with the mellanox vendor
string, that configures the ARC backend to support NPS400.

This patch series is intended for GCC 7, Stage 1, once it reopens.  I
am posting early in the hope that I could get an early review,
especially on patch #1, the build infrastructure, then if I need to
rework anything I can get started on it sooner.

I've run regression tests against a standard arc-elf target, and the
results look good.

All feedback appreciated.

Thanks,
Andrew

---

Andrew Burgess (10):
  gcc: Add support for mellanox nps400 arc variant
  gcc/arc: Add -munaligned-access option for nps400
  gcc/arc: generate jump tables in code section for nps400
  gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns
  gcc/arc: convert some constraints to define_constraint
  gcc/arc: Add support for nps400 cmem xld/xst instructions
  gcc/arc: Add nps400 bitops support
  gcc/arc: Mask integer 'L' operands to 32-bit
  gcc/arc: Add an nps400 specific testcase
  gcc/arc: Add __NPS400__ define for nps400 targets

 gcc/ChangeLog.NPS400                      | 122 +++++++
 gcc/config.gcc                            |  10 +
 gcc/config/arc/arc.c                      |  67 +++-
 gcc/config/arc/arc.h                      |  35 +-
 gcc/config/arc/arc.md                     | 567 +++++++++++++++++++++++-------
 gcc/config/arc/arc.opt                    |  14 +-
 gcc/config/arc/constraints.md             |  86 ++++-
 gcc/config/arc/predicates.md              |  19 +
 gcc/config/arc/t-nps400                   |  21 ++
 gcc/testsuite/ChangeLog.NPS400            |  44 +++
 gcc/testsuite/gcc.target/arc/cmem-1.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-2.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-3.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-4.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-5.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-6.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-7.c     |  26 ++
 gcc/testsuite/gcc.target/arc/cmem-ld.inc  |  16 +
 gcc/testsuite/gcc.target/arc/cmem-st.inc  |  18 +
 gcc/testsuite/gcc.target/arc/extzv-1.c    |  11 +
 gcc/testsuite/gcc.target/arc/insv-1.c     |  21 ++
 gcc/testsuite/gcc.target/arc/insv-2.c     |  18 +
 gcc/testsuite/gcc.target/arc/movb-1.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-2.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-3.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-4.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-5.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb_cl-1.c  |   9 +
 gcc/testsuite/gcc.target/arc/movb_cl-2.c  |  11 +
 gcc/testsuite/gcc.target/arc/movbi_cl-1.c |   9 +
 gcc/testsuite/gcc.target/arc/movh_cl-1.c  |  27 ++
 gcc/testsuite/gcc.target/arc/movl-1.c     |  17 +
 gcc/testsuite/gcc.target/arc/mrgb-1.c     |  14 +
 gcc/testsuite/gcc.target/arc/nps400-1.c   |  23 ++
 gcc/testsuite/gcc.target/arc/setmem-1.c   |  13 +
 gcc/testsuite/gcc.target/arc/setmem-2.c   |  18 +
 gcc/testsuite/gcc.target/arc/setmem-3.c   |  13 +
 gcc/testsuite/gcc.target/arc/setmem-4.c   |  18 +
 38 files changed, 1231 insertions(+), 161 deletions(-)
 create mode 100644 gcc/config/arc/t-nps400
 create mode 100644 gcc/testsuite/ChangeLog.NPS400
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-6.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-7.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-ld.inc
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-st.inc
 create mode 100644 gcc/testsuite/gcc.target/arc/extzv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movbi_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movh_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/mrgb-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/nps400-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-4.c

-- 
2.6.4

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

* [PATCH 05/10] gcc/arc: convert some constraints to define_constraint
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (4 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 03/10] gcc/arc: generate jump tables in code section for nps400 Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 06/10] gcc/arc: Add support for nps400 cmem xld/xst instructions Andrew Burgess
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

The define_memory_constraint allows for the address operand to be
reloaded into a base register.  However, for the constraints 'Us<' and
'Us>', which are used for matching 'push' and 'pop' instructions moving
the address into a base register is not helpful.  The constraints then
should be define_constraint, not define_memory_constraint.

Similarly the Usd constraint, used for generating small data area memory
accesses, can't have its operand loaded into a register as the
relocation for small data area symbols only works within ld/st
instructions.

gcc/ChangeLog:

	* config/arc/constraints.md (Usd): Convert to define_constraint.
	(Us<): Likewise.
	(Us>): Likewise.
---
 gcc/ChangeLog.NPS400          |  7 +++++++
 gcc/config/arc/constraints.md | 18 +++++++++++-------
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 71463df..5d1533c 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,10 @@
+2016-03-01  Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* config/arc/constraints.md (Usd): Convert to define_constraint.
+	(Us<): Likewise.
+	(Us>): Likewise.
+
 2016-02-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index 668b60a..b6954ad 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -269,11 +269,15 @@
   (and (match_code "mem")
        (match_test "compact_store_memory_operand (op, VOIDmode)")))
 
-(define_memory_constraint "Usd"
-  "@internal
-   A valid _small-data_ memory operand for ARCompact instructions"
-  (and (match_code "mem")
-       (match_test "compact_sda_memory_operand (op, VOIDmode)")))
+; Don't use define_memory_constraint here as the relocation patching
+; for small data symbols only works within a ld/st instruction and
+; define_memory_constraint may result in the address being calculated
+; into a register first.
+(define_constraint "Usd"
+   "@internal
+    A valid _small-data_ memory operand for ARCompact instructions"
+   (and (match_code "mem")
+        (match_test "compact_sda_memory_operand (op, VOIDmode)")))
 
 (define_memory_constraint "Usc"
   "@internal
@@ -283,7 +287,7 @@
 ;; ??? the assembler rejects stores of immediates to small data.
        (match_test "!compact_sda_memory_operand (op, VOIDmode)")))
 
-(define_memory_constraint "Us<"
+(define_constraint "Us<"
   "@internal
    Stack pre-decrement"
   (and (match_code "mem")
@@ -291,7 +295,7 @@
        (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
        (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")))
 
-(define_memory_constraint "Us>"
+(define_constraint "Us>"
   "@internal
    Stack post-increment"
   (and (match_code "mem")
-- 
2.6.4

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

* [PATCH 07/10] gcc/arc: Add nps400 bitops support
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (7 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 10/10] gcc/arc: Add __NPS400__ define for nps400 targets Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 02/10] gcc/arc: Add -munaligned-access option for nps400 Andrew Burgess
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

Add support for nps400 bit operation instructions.  There's a new flag
-mbitops that turns this feature on.  There are new instructions, some
changes to existing instructions, a new register class to support the
new instructions, and some new expand and peephole optimisations.

gcc/ChangeLog:

	* config/arc/arc.c (arc_conditional_register_usage): Take
	TARGET_RRQ_CLASS into account.
	(arc_print_operand): Support printing 'p' and 's' operands.
	* config/arc/arc.h (TARGET_NPS400_BITOPS_DEFAULT): Provide default
	as 0.
	(TARGET_RRQ_CLASS): Define.
	(IS_POWEROF2_OR_0_P): Define.
	* config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi
	alternatives.
	(*tst_movb): New define_insn.
	(*tst): Avoid recognition if it could prevent '*tst_movb'
	combination; replace c/CnL with c/Chs alternative.
	(*tst_bitfield_tst): New define_insn.
	(*tst_bitfield_asr): New define_insn.
	(*tst_bitfield): New define_insn.
	(andsi3_i): Add Rrq variant.
	(extzv): New define_expand.
	(insv): New define_expand.
	(*insv_i): New define_insn.
	(*movb): New define_insn.
	(*movb_signed): New define_insn.
	(*movb_high): New define_insn.
	(*movb_high_signed): New define_insn.
	(*movb_high_signed + 1): New define_split pattern.
	(*mrgb): New define_insn.
	(*mrgb + 1): New define_peephole2 pattern.
	(*mrgb + 2): New define_peephole2 pattern.
	* config/arc/arc.opt (mbitops): New option for nps400, uses
	TARGET_NPS400_BITOPS_DEFAULT.
	* config/arc/constraints.md (q): Make register class conditional.
	(Rrq): New register constraint.
	(Chs): New constraint.
	(Clo): New constraint.
	(Chi): New constraint.
	(Cbf): New constraint.
	(Cbn): New constraint.
	(C18): New constraint.
	(Cbi): New constraint.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/extzv-1.c: New file.
	* gcc.target/arc/insv-1.c: New file.
	* gcc.target/arc/insv-2.c: New file.
	* gcc.target/arc/movb-1.c: New file.
	* gcc.target/arc/movb-2.c: New file.
	* gcc.target/arc/movb-3.c: New file.
	* gcc.target/arc/movb-4.c: New file.
	* gcc.target/arc/movb-5.c: New file.
	* gcc.target/arc/movb_cl-1.c: New file.
	* gcc.target/arc/movb_cl-2.c: New file.
	* gcc.target/arc/movbi_cl-1.c: New file.
	* gcc.target/arc/movl-1.c: New file.
	* gcc.target/arc/mrgb-1.c: New file.
---
 gcc/ChangeLog.NPS400                      |  42 ++++
 gcc/config/arc/arc.c                      |  33 ++-
 gcc/config/arc/arc.h                      |   9 +
 gcc/config/arc/arc.md                     | 382 ++++++++++++++++++++++++++----
 gcc/config/arc/arc.opt                    |   4 +
 gcc/config/arc/constraints.md             |  58 ++++-
 gcc/testsuite/ChangeLog.NPS400            |  17 ++
 gcc/testsuite/gcc.target/arc/extzv-1.c    |  11 +
 gcc/testsuite/gcc.target/arc/insv-1.c     |  21 ++
 gcc/testsuite/gcc.target/arc/insv-2.c     |  18 ++
 gcc/testsuite/gcc.target/arc/movb-1.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-2.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-3.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-4.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-5.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb_cl-1.c  |   9 +
 gcc/testsuite/gcc.target/arc/movb_cl-2.c  |  11 +
 gcc/testsuite/gcc.target/arc/movbi_cl-1.c |   9 +
 gcc/testsuite/gcc.target/arc/movl-1.c     |  17 ++
 gcc/testsuite/gcc.target/arc/mrgb-1.c     |  14 ++
 20 files changed, 663 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/extzv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movbi_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/mrgb-1.c

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 2a0f820..8229d67 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,45 @@
+2013-02-19  Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* config/arc/arc.c (arc_conditional_register_usage): Take
+	TARGET_RRQ_CLASS into account.
+	(arc_print_operand): Support printing 'p' and 's' operands.
+	* config/arc/arc.h (TARGET_NPS400_BITOPS_DEFAULT): Provide default
+	as 0.
+	(TARGET_RRQ_CLASS): Define.
+	(IS_POWEROF2_OR_0_P): Define.
+	* config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi
+	alternatives.
+	(*tst_movb): New define_insn.
+	(*tst): Avoid recognition if it could prevent '*tst_movb'
+	combination; replace c/CnL with c/Chs alternative.
+	(*tst_bitfield_tst): New define_insn.
+	(*tst_bitfield_asr): New define_insn.
+	(*tst_bitfield): New define_insn.
+	(andsi3_i): Add Rrq variant.
+	(extzv): New define_expand.
+	(insv): New define_expand.
+	(*insv_i): New define_insn.
+	(*movb): New define_insn.
+	(*movb_signed): New define_insn.
+	(*movb_high): New define_insn.
+	(*movb_high_signed): New define_insn.
+	(*movb_high_signed + 1): New define_split pattern.
+	(*mrgb): New define_insn.
+	(*mrgb + 1): New define_peephole2 pattern.
+	(*mrgb + 2): New define_peephole2 pattern.
+	* config/arc/arc.opt (mbitops): New option for nps400, uses
+	TARGET_NPS400_BITOPS_DEFAULT.
+	* config/arc/constraints.md (q): Make register class conditional.
+	(Rrq): New register constraint.
+	(Chs): New constraint.
+	(Clo): New constraint.
+	(Chi): New constraint.
+	(Cbf): New constraint.
+	(Cbn): New constraint.
+	(C18): New constraint.
+	(Cbi): New constraint.
+
 2013-08-31  Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Andrew Burgess  <andrew.burgess@embecosm.com>
 
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 25ff693..a75f200 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1371,7 +1371,8 @@ arc_conditional_register_usage (void)
     {
       if (i < 29)
 	{
-	  if (TARGET_Q_CLASS && ((i <= 3) || ((i >= 12) && (i <= 15))))
+	  if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
+	      && ((i <= 3) || ((i >= 12) && (i <= 15))))
 	    arc_regno_reg_class[i] = ARCOMPACT16_REGS;
 	  else
 	    arc_regno_reg_class[i] = GENERAL_REGS;
@@ -1388,12 +1389,12 @@ arc_conditional_register_usage (void)
 	arc_regno_reg_class[i] = NO_REGS;
     }
 
-  /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS has not been activated.  */
+  /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
+     has not been activated.  */
+  if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
+    CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
   if (!TARGET_Q_CLASS)
-    {
-      CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
-      CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
-    }
+    CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
 
   gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
 
@@ -2935,6 +2936,8 @@ static int output_scaled = 0;
     'Z': log2(x+1)-1
     'z': log2
     'M': log2(~x)
+    'p': bit Position of lsb
+    's': size of bit field
     '#': condbranch delay slot suffix
     '*': jump delay slot suffix
     '?' : nonjump-insn suffix for conditional execution or short instruction
@@ -2985,6 +2988,24 @@ arc_print_operand (FILE *file, rtx x, int code)
 
       return;
 
+    case 'p':
+      if (GET_CODE (x) == CONST_INT)
+	fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
+      else
+	output_operand_lossage ("invalid operand to %%p code");
+      return;
+
+    case 's':
+      if (GET_CODE (x) == CONST_INT)
+	{
+	  HOST_WIDE_INT i = INTVAL (x);
+	  HOST_WIDE_INT s = exact_log2 (i & -i);
+	  fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
+	}
+      else
+	output_operand_lossage ("invalid operand to %%s code");
+      return;
+
     case '#' :
       /* Conditional branches depending on condition codes.
 	 Note that this is only for branches that were known to depend on
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 28c3ef1..f278bf5 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -318,10 +318,18 @@ along with GCC; see the file COPYING3.  If not see
 #define UNALIGNED_ACCESS_DEFAULT 0
 #endif
 
+#ifndef TARGET_NPS400_BITOPS_DEFAULT
+#define TARGET_NPS400_BITOPS_DEFAULT 0
+#endif
+
 #ifndef TARGET_NPS400_CMEM_DEFAULT
 #define TARGET_NPS400_CMEM_DEFAULT 0
 #endif
 
+/* Enable the RRQ instruction alternatives.  */
+
+#define TARGET_RRQ_CLASS TARGET_NPS400_BITOPS
+
 /* Target machine storage layout.  */
 
 /* We want zero_extract to mean the same
@@ -1025,6 +1033,7 @@ extern int arc_initial_elimination_offset(int from, int to);
 
 /* Is the argument a const_int rtx, containing an exact power of 2 */
 #define  IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X))
+#define  IS_POWEROF2_OR_0_P(X) (! ( (X) & ((X) - 1)))
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 33e6dee..e318fc8 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -691,8 +691,8 @@
 ; insns it should lengthen the return insn.
 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
 (define_insn "*movsi_insn"
-  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
-	(match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
+  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,w,w,w,w,???w,?w,w,Rcq#q,w,Rcq,S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
+	(match_operand:SI 1 "move_src_operand"  "cL,cP,Rcq#q,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)
    || (CONSTANT_P (operands[1])
@@ -707,29 +707,32 @@
    mov%? %0,%1		;3
    mov%? %0,%1		;4
    ror %0,((%1*2+1) & 0x3f) ;5
-   mov%? %0,%1		;6
-   add %0,%S1		;7
+   movl.cl %0,%1       ;6
+   movh.cl %0,%L1>>16  ;7
+   * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\";
+   mov%? %0,%1		;9
+   add %0,%S1		;10
    * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
-   mov%? %0,%S1%&	;9
-   mov%? %0,%S1		;10
-   ld%? %0,%1%&		;11
-   st%? %1,%0%&		;12
+   mov%? %0,%S1%&	;12
+   mov%? %0,%S1		;13
+   ld%? %0,%1%&		;14
+   st%? %1,%0%&		;15
    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
-   ld%? %0,%1%&		;15
-   xld%U1 %0,%1         ;16
-   ld%U1%V1 %0,%1	;17
-   xst%U0 %1,%0         ;18
-   st%U0%V0 %1,%0       ;19
-   st%U0%V0 %1,%0       ;20
-   st%U0%V0 %S1,%0      ;21"
-  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
+   ld%? %0,%1%&		;18
+   xld%U1 %0,%1                ;19
+   ld%U1%V1 %0,%1	;20
+   xst%U0 %1,%0                ;21
+   st%U0%V0 %1,%0       ;22
+   st%U0%V0 %1,%0       ;23
+   st%U0%V0 %S1,%0      ;24"
+  [(set_attr "type" "move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
    ; Use default length for iscompact to allow for COND_EXEC.  But set length
    ; of Crr to 4.
-   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
-   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
+   (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
+   (set_attr "predicable" "yes,no,yes,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 ;; Sometimes generated by the epilogue code.  We don't want to
 ;; recognize these addresses in general, because the limm is costly,
@@ -800,6 +803,24 @@
    (set_attr "cond" "set_zn")
    (set_attr "length" "4")])
 
+; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
+; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
+; even if we don't need the clobber.
+(define_insn_and_split "*tst_movb"
+  [(set
+     (match_operand 0 "cc_register" "")
+     (match_operator 4 "zn_compare_operator"
+       [(and:SI
+	  (match_operand:SI 1 "register_operand"  "%Rcq,Rcq, c,  c,  c,  c,Rrq,  3,  c")
+	  (match_operand:SI 2 "nonmemory_operand"  "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
+	(const_int 0)]))
+   (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
+  "TARGET_NPS400_BITOPS"
+  "movb.f.cl %3,%1,%p2,%p2,%s2"
+  "reload_completed
+   && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
+  [(set (match_dup 0) (match_dup 4))])
+
 (define_insn "*tst"
   [(set
      (match_operand 0 "cc_register" "")
@@ -808,12 +829,14 @@
 	  (match_operand:SI 1 "register_operand"
 	   "%Rcq,Rcq, c, c, c,  c,  c,  c")
 	  (match_operand:SI 2 "nonmemory_operand"
-	   " Rcq,C0p,cI,cL,C1p,Ccp,CnL,Cal"))
+	   " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
 	(const_int 0)]))]
-  "(register_operand (operands[1], SImode)
-    && nonmemory_operand (operands[2], SImode))
-   || (memory_operand (operands[1], SImode)
-       && satisfies_constraint_Cux (operands[2]))"
+  "reload_completed
+   || !satisfies_constraint_Cbf (operands[2])
+   || satisfies_constraint_C0p (operands[2])
+   || satisfies_constraint_I (operands[2])
+   || satisfies_constraint_C1p (operands[2])
+   || satisfies_constraint_Chs (operands[2])"
   "*
     switch (which_alternative)
     {
@@ -826,17 +849,79 @@
     case 5:
       return \"bclr%?.f 0,%1,%M2%&\";
     case 6:
-      return \"bic%?.f 0,%1,%n2-1\";
+      return \"asr.f 0,%1,%p2\";
     default:
       gcc_unreachable ();
     }
   "
   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
-   (set_attr "type" "compare")
+   (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
    (set_attr "length" "*,*,4,4,4,4,4,8")
    (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
    (set_attr "cond" "set_zn")])
 
+; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
+; combine will do that and not try the AND.
+
+; It would take 66 constraint combinations to describe the zero_extract
+; constants that are covered by the 12-bit signed constant for tst
+; (excluding the ones that are better done by mov or btst).
+; so we rather use an extra pattern for tst;
+; since this is about constants, reload shouldn't care.
+(define_insn "*tst_bitfield_tst"
+  [(set (match_operand:CC_ZN 0 "cc_set_register" "")
+	(match_operator 4 "zn_compare_operator"
+	  [(zero_extract:SI
+	     (match_operand:SI 1 "register_operand"  "c")
+	     (match_operand:SI 2 "const_int_operand" "n")
+	     (match_operand:SI 3 "const_int_operand" "n"))
+	   (const_int 0)]))]
+  "INTVAL (operands[2]) > 1
+   && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
+       || (INTVAL (operands[3]) <= 11
+	   && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
+  "tst %1,(1<<%2)-1<<%3"
+  [(set_attr "type" "compare")
+   (set_attr "cond" "set_zn")
+   (set_attr "length" "4")])
+
+; Likewise for asr.f.
+(define_insn "*tst_bitfield_asr"
+  [(set (match_operand:CC_ZN 0 "cc_set_register" "")
+	(match_operator 4 "zn_compare_operator"
+	  [(zero_extract:SI
+	     (match_operand:SI 1 "register_operand"  "c")
+	     (match_operand:SI 2 "const_int_operand" "n")
+	     (match_operand:SI 3 "const_int_operand" "n"))
+	   (const_int 0)]))]
+  "INTVAL (operands[2]) > 1
+   && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
+  "asr.f 0,%1,%3"
+  [(set_attr "type" "shift")
+   (set_attr "cond" "set_zn")
+   (set_attr "length" "4")])
+
+(define_insn "*tst_bitfield"
+  [(set (match_operand:CC_ZN 0 "cc_set_register" "")
+	(match_operator 5 "zn_compare_operator"
+	  [(zero_extract:SI
+	     (match_operand:SI 1 "register_operand" "%Rcqq,c,  c,Rrq,c")
+	     (match_operand:SI 2 "const_int_operand"    "N,N,  n,Cbn,n")
+	     (match_operand:SI 3 "const_int_operand"    "n,n,C_0,Cbn,n"))
+	   (const_int 0)]))
+   (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
+  ""
+  "@
+   btst%? %1,%3
+   btst %1,%3
+   bmsk.f 0,%1,%2-1
+   movb.f.cl %4,%1,%3,%3,%2
+   and.f 0,%1,((1<<%2)-1)<<%3"
+  [(set_attr "iscompact" "maybe,false,false,false,false")
+   (set_attr "type" "compare,compare,compare,shift,compare")
+   (set_attr "cond" "set_zn")
+   (set_attr "length" "*,4,4,4,8")])
+
 (define_insn "*commutative_binary_comparison"
   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
 	(match_operator:CC_ZN 5 "zn_compare_operator"
@@ -2947,30 +3032,40 @@
      operands[1] = arc_rewrite_small_data (operands[1]);")
 
 (define_insn "andsi3_i"
-  [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,  w,  w,  w,  w,w,Rcw,  w,  W")
-	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,   0,   0,Rcqq,  0,  c,  0,  0,  0,  0,  c,  c,  c,  c,0,  0,  c,  o")
-		(match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, C1p, Ccp, Cux, cL,  0,C1p,Ccp,CnL,  I, Lc,C1p,Ccp,CnL,I,Cal,Cal,Cux")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,w,w,w,w,Rrq,w,Rcw,w,W")
+	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,0,0,Rcqq,0,c,0,0,0,0,c,c,c,c,Rrq,0,0,c,o")
+		(match_operand:SI 2 "nonmemory_operand" "Rcqq,0,C1p,Ccp,Cux,cL,0,C1p,Ccp,CnL,I,Lc,C1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
   "(register_operand (operands[1], SImode)
     && nonmemory_operand (operands[2], SImode))
    || (memory_operand (operands[1], SImode)
        && satisfies_constraint_Cux (operands[2]))"
-  "*
 {
   switch (which_alternative)
     {
-    case 0: case 5: case 10: case 11: case 15: case 16: case 17:
-      return \"and%? %0,%1,%2%&\";
+    case 0: case 5: case 10: case 11: case 16: case 17: case 18:
+      return "and%? %0,%1,%2%&";
     case 1: case 6:
-      return \"and%? %0,%2,%1%&\";
+      return "and%? %0,%2,%1%&";
     case 2: case 7: case 12:
-      return \"bmsk%? %0,%1,%Z2%&\";
+      return "bmsk%? %0,%1,%Z2%&";
     case 3: case 8: case 13:
-      return \"bclr%? %0,%1,%M2%&\";
+      return "bclr%? %0,%1,%M2%&";
     case 4:
       return (INTVAL (operands[2]) == 0xff
-	      ? \"extb%? %0,%1%&\" : \"ext%_%? %0,%1%&\");
+	      ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
-    case 18:
+    case 15:
+      return "movb.cl %0,%1,%p2,%p2,%s2";
+
+    case 19:
+      const char *tmpl;
+
+      if (satisfies_constraint_Ucm (operands[1]))
+	tmpl = (INTVAL (operands[2]) == 0xff
+		? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
+      else
+	tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
+
       if (TARGET_BIG_ENDIAN)
 	{
 	  rtx xop[2];
@@ -2978,21 +3073,19 @@
 	  xop[0] = operands[0];
 	  xop[1] = adjust_address (operands[1], QImode,
 				   INTVAL (operands[2]) == 0xff ? 3 : 2);
-	  output_asm_insn (INTVAL (operands[2]) == 0xff
-			   ? \"ldb %0,%1\" : \"ld%_ %0,%1\",
-			   xop);
-	  return \"\";
+	  output_asm_insn (tmpl, xop);
+	  return "";
 	}
-      return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ld%_ %0,%1\";
+      return tmpl;
     default:
       gcc_unreachable ();
     }
-}"
-  [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
-   (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load")
-   (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
-   (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no")
-   (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
+}
+  [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
+   (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
+   (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
+   (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
+   (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
 
 ; combiner splitter, pattern found in ldtoa.c .
 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
@@ -5642,7 +5735,6 @@
   [(set_attr "length" "4")
    (set_attr "type" "misc")])
 
-
 ;; FPU/FPX expands
 
 ;;add
@@ -5785,6 +5877,196 @@
    gcc_unreachable ();
  ")
 
+(define_expand "extzv"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "")
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" "")))]
+  "TARGET_NPS400_BITOPS")
+
+; We need a sanity check in the instuction predicate because combine
+; will throw any old rubbish at us and see what sticks.
+(define_insn "*extzv_i"
+  [(set (match_operand:SI 0 "register_operand" "=Rrq")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
+			 (match_operand:SI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))]
+  "TARGET_NPS400_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
+  "movb.cl %0,%1,0,%3,%2"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_expand "insv"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
+			 (match_operand:SI 1 "const_int_operand" "")
+			 (match_operand:SI 2 "const_int_operand" ""))
+	(match_operand:SI 3 "nonmemory_operand" ""))]
+  "TARGET_NPS400_BITOPS"
+{
+  int size = INTVAL (operands[1]);
+
+  if (size != 1 && size != 2 && size != 4 && size != 8)
+    operands[3] = force_reg (SImode, operands[3]);
+})
+
+(define_insn "*insv_i"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
+			 (match_operand:SI 1 "const_int_operand" "C18,n")
+			 (match_operand:SI 2 "const_int_operand" "n,n"))
+	(match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
+  "TARGET_NPS400_BITOPS
+   && (register_operand (operands[3], SImode)
+       || satisfies_constraint_C18 (operands[1]))"
+  "@
+   movbi %0,%0,%3,%2,%1
+   movb %0,%0,%3,%2,0,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_insn "*movb"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
+			 (match_dup 1)
+			 (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS400_BITOPS"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_insn "*movb_signed"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
+			 (match_dup 1)
+			 (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS400_BITOPS"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_insn "*movb_high"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
+		     (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS400_BITOPS
+   && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+; N.B.: when processing signed bitfields that fit in the top half of
+; a word, gcc will use a narrow sign extending load, and in this case
+; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
+(define_insn "*movb_high_signed"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
+		     (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS400_BITOPS
+   && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
+			   (match_operand:SI 2 "const_int_operand" ""))
+		(subreg:SI (match_operand 3 "") 0)))]
+  "TARGET_NPS400_BITOPS
+   && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])"
+  [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
+   (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
+	(match_dup 1))]
+  "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
+
+(define_insn "*mrgb"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(zero_extract:SI (match_dup 0) (match_dup 1)
+			 (match_operand:SI 3 "const_int_operand" "n")))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 4 "const_int_operand" "n")
+			 (match_operand:SI 5 "const_int_operand" "n"))
+	(zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
+			 (match_dup 4)
+			 (match_operand:SI 7 "const_int_operand" "n")))]
+  "TARGET_NPS400_BITOPS"
+{
+  output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
+  /* The ;%? updates the known unalignment.  */
+  return arc_short_long (insn, ";%?", "nop_s");
+}
+  [(set_attr "type" "shift")
+   (set_attr "length" "6")
+   (set_attr "iscompact" "true")])
+
+;; combine fumbles combination of two movb patterns, and then the
+;; combination is rejected by combinable_i3pat.
+;; Thus, we can only use a peephole2 to combine two such insns.
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "register_operand" ""))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" ""))
+	(zero_extract:SI (match_dup 1)
+			 (match_dup 2)
+			 (match_operand:SI 4 "const_int_operand" "")))
+   (match_operand 9) ; unrelated insn scheduled here
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 5 "const_int_operand" "")
+			 (match_operand:SI 6 "const_int_operand" ""))
+	(zero_extract:SI (match_operand:SI 7 "register_operand" "")
+			 (match_dup 5)
+			 (match_operand:SI 8 "const_int_operand" "")))]
+  "TARGET_NPS400_BITOPS
+   // Check that the second movb doesn't clobber an input of the extra insn.
+   && !reg_overlap_mentioned_p (operands[0], operands[9])
+   // And vice versa.
+   && !reg_set_p (operands[0], operands[9])
+   && !reg_set_p (operands[7], operands[9])"
+  [(set (match_dup 0) (match_dup 1))
+   (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
+		   (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
+	      (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
+		   (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
+   (match_dup 9)])
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "register_operand" ""))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" ""))
+	(zero_extract:SI (match_dup 1)
+			 (match_dup 2)
+			 (match_operand:SI 4 "const_int_operand" "")))
+   (set (match_dup 1) (match_operand 8))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 5 "const_int_operand" "")
+			 (match_operand:SI 6 "const_int_operand" ""))
+	(zero_extract:SI (match_dup 1) (match_dup 5)
+			 (match_operand:SI 7 "const_int_operand" "")))]
+  "TARGET_NPS400_BITOPS
+   && !reg_overlap_mentioned_p (operands[0], operands[8])"
+  [(set (match_dup 0) (match_dup 1))
+   (set (match_dup 1) (match_dup 8))
+   (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
+		   (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
+	      (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
+		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
+   (match_dup 1)])
+
 ;; include the arc-FPX instructions
 (include "fpx.md")
 
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 4816238..3411599 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -457,6 +457,10 @@ Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
 EnumValue
 Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
 
+mbitops
+Target Report Var(TARGET_NPS400_BITOPS) Init(TARGET_NPS400_BITOPS_DEFAULT) Condition(ARC_NPS400)
+Enable use of NPS400 bit operations.
+
 mcmem
 Target Report Var(TARGET_NPS400_CMEM) Init(TARGET_NPS400_CMEM_DEFAULT) Condition(ARC_NPS400)
 Enable use of NPS400 xld/xst extension.
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index 409e7d6..37370dd 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -66,10 +66,18 @@
    Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30},
    @code{blink}:@code{r31},")
 
-(define_register_constraint "q" "ARCOMPACT16_REGS"
+(define_register_constraint "q" "TARGET_Q_CLASS ? ARCOMPACT16_REGS : NO_REGS"
   "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
    @code{r12}-@code{r15}")
 
+; NPS400 bitfield instructions require registers from the r0-r3,r12-r15
+; range, and thus we need a register class and constraint that works
+; independently of size optimization.
+(define_register_constraint
+ "Rrq" "TARGET_RRQ_CLASS ? ARCOMPACT16_REGS : NO_REGS"
+  "Registers usable in NPS400 bitfield instructions: @code{r0}-@code{r3},
+   @code{r12}-@code{r15}")
+
 (define_register_constraint "e" "AC16_BASE_REGS"
   "Registers usable as base-regs of memory addresses in ARCompact 16-bit memory
    instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}")
@@ -236,12 +244,60 @@
   (and (match_code "const_int")
        (match_test "ival == 0xff || ival == 0xffff")))
 
+(define_constraint "Chs"
+ "@internal
+  constant for a highpart that can be checked with a shift (asr.f 0,rn,m)"
+  (and (match_code "const_int")
+       (match_test "IS_POWEROF2_P (-ival)")))
+
+(define_constraint "Clo"
+ "@internal
+  constant that fits into 16 lower bits, for movl"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS400_BITOPS")
+       (match_test "(ival & ~0xffffU) == 0")))
+
+(define_constraint "Chi"
+ "@internal
+  constant that fits into 16 higher bits, for movh_i"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS400_BITOPS")
+       (match_test "trunc_int_for_mode (ival >> 16, HImode) << 16 == ival")))
+
+(define_constraint "Cbf"
+ "@internal
+  a mask for a bit field, for AND using movb_i"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS400_BITOPS")
+       (match_test "IS_POWEROF2_OR_0_P (ival + (ival & -ival))")))
+
+(define_constraint "Cbn"
+ "@internal
+  a constant integer, valid only if TARGET_NPS400_BITOPS is true"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS400_BITOPS")))
+
+(define_constraint "C18"
+ "@internal
+  1,2,4 or 8"
+  (and (match_code "const_int")
+       (match_test "ival == 1 || ival == 2 || ival == 4 || ival == 8")))
+
 (define_constraint "Crr"
  "@internal
   constant that can be loaded with ror b,u6"
   (and (match_code "const_int")
        (match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()")))
 
+(define_constraint "Cbi"
+ "@internal
+  constant that can be loaded with movbi.cl"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS400_BITOPS")
+       (match_test "!ival
+		    || ((ival & 0xffffffffUL) >> exact_log2 (ival & -ival)
+			<= 0xff)")))
+
 ;; Floating-point constraints
 
 (define_constraint "G"
diff --git a/gcc/testsuite/ChangeLog.NPS400 b/gcc/testsuite/ChangeLog.NPS400
index bc5e68c..22dec32 100644
--- a/gcc/testsuite/ChangeLog.NPS400
+++ b/gcc/testsuite/ChangeLog.NPS400
@@ -1,3 +1,20 @@
+2013-02-19  Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gcc.target/arc/extzv-1.c: New file.
+	* gcc.target/arc/insv-1.c: New file.
+	* gcc.target/arc/insv-2.c: New file.
+	* gcc.target/arc/movb-1.c: New file.
+	* gcc.target/arc/movb-2.c: New file.
+	* gcc.target/arc/movb-3.c: New file.
+	* gcc.target/arc/movb-4.c: New file.
+	* gcc.target/arc/movb-5.c: New file.
+	* gcc.target/arc/movb_cl-1.c: New file.
+	* gcc.target/arc/movb_cl-2.c: New file.
+	* gcc.target/arc/movbi_cl-1.c: New file.
+	* gcc.target/arc/movl-1.c: New file.
+	* gcc.target/arc/mrgb-1.c: New file.
+
 2013-08-09  Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Andrew Burgess  <andrew.burgess@embecosm.com>
 
diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c b/gcc/testsuite/gcc.target/arc/extzv-1.c
new file mode 100644
index 0000000..465a377
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/extzv-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct foo { unsigned a: 3, b: 5, c: 24; };
+
+int
+f (struct foo i)
+{
+  return i.b;
+}
+/* { dg-final { scan-assembler "movb\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c b/gcc/testsuite/gcc.target/arc/insv-1.c
new file mode 100644
index 0000000..cbba28e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/insv-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+/* ??? Irrespective of insn set, generated code for this is a mess.  */
+struct foo { unsigned a: 3, b: 8, c: 21; };
+
+struct foo
+f (struct foo i)
+{
+  i.b = 42;
+  return i;
+}
+
+struct foo
+g (struct foo i, int j)
+{
+  i.b = j;
+  return i;
+}
+/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
+/* { dg-final { scan-assembler "movb\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c b/gcc/testsuite/gcc.target/arc/insv-2.c
new file mode 100644
index 0000000..7c468b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/insv-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct foo { unsigned a: 3, b: 8, c: 21; } bar;
+
+void
+f (void)
+{
+  bar.b = 42;
+}
+
+void
+g (int j)
+{
+  bar.b = j;
+}
+/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
+/* { dg-final { scan-assembler "movb\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
new file mode 100644
index 0000000..bcd9ea3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct { unsigned a: 5, b: 8, c: 19; } foo;
+struct { unsigned a: 3, b: 8, c: 21; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
new file mode 100644
index 0000000..5d1aac8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct { unsigned a: 23, b: 9; } foo;
+struct { unsigned a: 23, b: 9; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c b/gcc/testsuite/gcc.target/arc/movb-3.c
new file mode 100644
index 0000000..77cac4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct { int a: 23, b: 9; } foo;
+struct { int a: 23, b: 9; } bar;
+
+void
+f (void)
+{
+  bar.a = foo.a;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *23" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *9, *9, *23" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c b/gcc/testsuite/gcc.target/arc/movb-4.c
new file mode 100644
index 0000000..c45e35a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct { int a: 13, b: 19; } foo;
+struct { int a: 13, b: 19; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *13, *13, *19" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *19" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
new file mode 100644
index 0000000..6de13ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-5.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct { int a: 23, b: 9; } foo;
+struct { int a: 23, b: 9; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
new file mode 100644
index 0000000..7d2c388
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+int
+f (int i)
+{
+  return i & 0x0ffff000;
+}
+/* { dg-final { scan-assembler "movb\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
new file mode 100644
index 0000000..21df97b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+extern void g (void);
+int
+f (int i)
+{
+  if (i & 0x0ffff000)
+    g ();
+}
+/* { dg-final { scan-assembler "movb\.f\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
new file mode 100644
index 0000000..af74b22
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+int
+f (int i)
+{
+  return 0x6e00;
+}
+/* { dg-final { scan-assembler "mov(bi|l)\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c b/gcc/testsuite/gcc.target/arc/movl-1.c
new file mode 100644
index 0000000..f4f810a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movl-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+int
+f (void)
+{
+  return 0xd00d;
+}
+
+int
+g (void)
+{
+  return 0x7ff00000;
+}
+
+/* { dg-final { scan-assembler "movl\.cl\[ \t\]" } } */
+/* { dg-final { scan-assembler "movh\.cl\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mrgb-1.c b/gcc/testsuite/gcc.target/arc/mrgb-1.c
new file mode 100644
index 0000000..11c9fe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/mrgb-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct { unsigned a: 5, b: 8, c: 8, d: 11; } foo;
+struct { unsigned a: 3, b: 8, c: 21; } bar;
+
+void
+f (void)
+{
+  foo.b = foo.c;
+  foo.c = bar.b;
+}
+/* { dg-final { scan-assembler "mrgb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *13, *8, *13, *3, *8" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "mrgb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *11, *8, *11, *21, *8" { target arceb-*-* } } } */
-- 
2.6.4

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

* [PATCH 08/10] gcc/arc: Mask integer 'L' operands to 32-bit
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (2 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 09/10] gcc/arc: Add an nps400 specific testcase Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 03/10] gcc/arc: generate jump tables in code section for nps400 Andrew Burgess
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

When formatting 'L' operands (least significant word) only print
32-bits, don't sign extend to 64-bits.

This commit could really be applied directly to the current GCC trunk,
however, the only test I have for this issue right now relies on the
nps400 bitops support.

gcc/ChangeLog:

	* config/arc/arc.c (arc_print_operand): Print integer 'L' operands
	as 32-bits.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/movh_cl-1.c: New file.
---
 gcc/ChangeLog.NPS400                     |  6 ++++++
 gcc/config/arc/arc.c                     | 10 ++++------
 gcc/testsuite/ChangeLog.NPS400           |  4 ++++
 gcc/testsuite/gcc.target/arc/movh_cl-1.c | 27 +++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/movh_cl-1.c

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 8229d67..146370c 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,9 @@
+2016-01-19  Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* config/arc/arc.c (arc_print_operand): Print integer 'L' operands
+	as 32-bits.
+
 2013-02-19  Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Andrew Burgess  <andrew.burgess@embecosm.com>
 
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index a75f200..dc885d3 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -3176,18 +3176,16 @@ arc_print_operand (FILE *file, rtx x, int code)
       else if (GET_CODE (x) == CONST_INT
 	       || GET_CODE (x) == CONST_DOUBLE)
 	{
-	  rtx first, second;
+	  rtx first, second, word;
 
 	  split_double (x, &first, &second);
 
 	  if((WORDS_BIG_ENDIAN) == 0)
-	      fprintf (file, "0x%08" PRIx64,
-		       code == 'L' ? INTVAL (first) : INTVAL (second));
+	    word = (code == 'L' ? first : second);
 	  else
-	      fprintf (file, "0x%08" PRIx64,
-		       code == 'L' ? INTVAL (second) : INTVAL (first));
-
+	    word = (code == 'L' ? second : first);
 
+	  fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
 	  }
       else
 	output_operand_lossage ("invalid operand to %%H/%%L code");
diff --git a/gcc/testsuite/ChangeLog.NPS400 b/gcc/testsuite/ChangeLog.NPS400
index 22dec32..d658bd9 100644
--- a/gcc/testsuite/ChangeLog.NPS400
+++ b/gcc/testsuite/ChangeLog.NPS400
@@ -1,3 +1,7 @@
+2016-01-19  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gcc.target/arc/movh_cl-1.c: New file.
+
 2013-02-19  Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Andrew Burgess  <andrew.burgess@embecosm.com>
 
diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
new file mode 100644
index 0000000..8fbea7e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -mbitops" } */
+
+struct thing
+{
+  union
+  {
+    int raw;
+    struct
+    {
+      unsigned a : 1;
+      unsigned b : 1;
+    };
+  };
+};
+
+extern void func (int);
+
+void
+blah ()
+{
+  struct thing xx;
+  xx.a = xx.b = 1;
+  func (xx.raw);
+}
+
+/* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
-- 
2.6.4

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

* [PATCH 10/10] gcc/arc: Add __NPS400__ define for nps400 targets
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (6 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 06/10] gcc/arc: Add support for nps400 cmem xld/xst instructions Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 07/10] gcc/arc: Add nps400 bitops support Andrew Burgess
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

Arrange to have the define __NPS400__ defined when compiling code for
Mellanox NPS400 ARC variant.

gcc/ChangeLog:

	* conig/arc/arc.h (TARGET_CPU_CPP_BUILTINS): Add __NPS400__.
---
 gcc/ChangeLog.NPS400 | 4 ++++
 gcc/config/arc/arc.h | 2 ++
 2 files changed, 6 insertions(+)

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 146370c..e1889b9 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,7 @@
+2016-02-08  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* conig/arc/arc.h (TARGET_CPU_CPP_BUILTINS): Add __NPS400__.
+
 2016-01-19  Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Andrew Burgess  <andrew.burgess@embecosm.com>
 
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index f278bf5..0330ab4 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -120,6 +120,8 @@ along with GCC; see the file COPYING3.  If not see
 		    ? "__BIG_ENDIAN__" : "__LITTLE_ENDIAN__"); \
     if (TARGET_BIG_ENDIAN)		\
       builtin_define ("__big_endian__"); \
+    if (ARC_NPS400)			\
+      builtin_define ("__NPS400__");	\
 } while(0)
 
 #if DEFAULT_LIBC == LIBC_UCLIBC
-- 
2.6.4

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

* [PATCH 09/10] gcc/arc: Add an nps400 specific testcase
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
  2016-03-04 13:25 ` [PATCH 01/10] gcc: Add support for mellanox nps400 arc variant Andrew Burgess
  2016-03-04 13:26 ` [PATCH 04/10] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 08/10] gcc/arc: Mask integer 'L' operands to 32-bit Andrew Burgess
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

This test case triggered a bug caused by VOIDmode not being handled in
proper_comparison_operator, this problem was fixed with a commit on
2016-01-27 by Claudiu Zissulescu, adding this test case for coverage.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/nps400-1.c: New file.
---
 gcc/testsuite/ChangeLog.NPS400          |  4 ++++
 gcc/testsuite/gcc.target/arc/nps400-1.c | 23 +++++++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/arc/nps400-1.c

diff --git a/gcc/testsuite/ChangeLog.NPS400 b/gcc/testsuite/ChangeLog.NPS400
index d658bd9..20f88d0 100644
--- a/gcc/testsuite/ChangeLog.NPS400
+++ b/gcc/testsuite/ChangeLog.NPS400
@@ -1,3 +1,7 @@
+2016-02-06  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gcc.target/arc/nps400-1.c: New file.
+
 2016-01-19  Andrew Burgess  <andrew.burgess@embecosm.com>
 
 	* gcc.target/arc/movh_cl-1.c: New file.
diff --git a/gcc/testsuite/gcc.target/arc/nps400-1.c b/gcc/testsuite/gcc.target/arc/nps400-1.c
new file mode 100644
index 0000000..57d6800
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/nps400-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mq-class -mbitops -munaligned-access -mcmem -O2 -fno-strict-aliasing" } */
+
+enum npsdp_mem_space_type {
+  NPSDP_EXTERNAL_MS = 1
+};
+struct npsdp_ext_addr {
+  struct {
+    struct {
+      enum npsdp_mem_space_type mem_type : 1;
+      unsigned msid : 5;
+    };
+  };
+  char user_space[];
+} a;
+char b;
+void fn1() {
+  ((struct npsdp_ext_addr *)a.user_space)->mem_type = NPSDP_EXTERNAL_MS;
+  ((struct npsdp_ext_addr *)a.user_space)->msid =
+      ((struct npsdp_ext_addr *)a.user_space)->mem_type ? 1 : 10;
+  while (b)
+    ;
+}
-- 
2.6.4

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

* [PATCH 06/10] gcc/arc: Add support for nps400 cmem xld/xst instructions
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (5 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 05/10] gcc/arc: convert some constraints to define_constraint Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 10/10] gcc/arc: Add __NPS400__ define for nps400 targets Andrew Burgess
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

This commit adds support for NPS400 cmem memory sections.  Data to be
placed into cmem memory is placed into a section ".cmem",
".cmem_shared", or ".cmem_private".

There are restrictions on how instructions can be used to operate on
data held in cmem memory, this is reflected by the introduction of new
operand constraints (Uex/Ucm), and modifications to some instructions to
make use of these constraints.

gcc/ChangeLog:

	* config/arc/arc.h (SYMBOL_FLAG_CMEM): Define.
	(TARGET_NPS400_CMEM_DEFAULT): Provide default definition.
	* config/arc/arc.c (arc_address_cost): Return 0 for cmem_address.
	(arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated.
	* config/arc/arc.opt (mcmem): New option.
	* config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative,
	supply length for r/m alternative.
	(*extendqisi2_ac): Likewise.
	(*extendhisi2_i): Add r/Uex alternative, supply length for r/m and
	r/Uex alternative.
	(movqi_insn): Add r/Ucm and Ucm/?Rac alternatives.
	(movhi_insn): Likewise.
	(movsi_insn): Add r/Ucm,Ucm/w alternatives.
	(*zero_extendqihi2_i): Add r/Ucm alternative.
	(*zero_extendqisi2_ac): Likewise.
	(*zero_extendhisi2_i): Likewise.
	* config/arc/constraints.md (Uex): New memory constraint.
	(Ucm): New define_constraint.
	* config/arc/predicates.md (long_immediate_loadstore_operand):
	Return 0 for MEM with cmem_address address.
	(cmem_address_0): New predicates.
	(cmem_address_1): Likewise.
	(cmem_address_2): Likewise.
	(cmem_address): Likewise.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/cmem-1.c: New file.
	* gcc.target/arc/cmem-2.c: New file.
	* gcc.target/arc/cmem-3.c: New file.
	* gcc.target/arc/cmem-4.c: New file.
	* gcc.target/arc/cmem-5.c: New file.
	* gcc.target/arc/cmem-6.c: New file.
	* gcc.target/arc/cmem-7.c: New file.
	* gcc.target/arc/cmem-ld.inc: New file.
	* gcc.target/arc/cmem-st.inc: New file.
---
 gcc/ChangeLog.NPS400                     |  28 ++++++++
 gcc/config/arc/arc.c                     |  20 ++++++
 gcc/config/arc/arc.h                     |   5 ++
 gcc/config/arc/arc.md                    | 115 +++++++++++++++++--------------
 gcc/config/arc/arc.opt                   |   4 ++
 gcc/config/arc/constraints.md            |  14 +++-
 gcc/config/arc/predicates.md             |  19 +++++
 gcc/testsuite/ChangeLog.NPS400           |  13 ++++
 gcc/testsuite/gcc.target/arc/cmem-1.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-2.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-3.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-4.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-5.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-6.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-7.c    |  26 +++++++
 gcc/testsuite/gcc.target/arc/cmem-ld.inc |  16 +++++
 gcc/testsuite/gcc.target/arc/cmem-st.inc |  18 +++++
 17 files changed, 287 insertions(+), 51 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-6.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-7.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-ld.inc
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-st.inc

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 5d1533c..2a0f820 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,31 @@
+2013-08-31  Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* config/arc/arc.h (SYMBOL_FLAG_CMEM): Define.
+	(TARGET_NPS400_CMEM_DEFAULT): Provide default definition.
+	* config/arc/arc.c (arc_address_cost): Return 0 for cmem_address.
+	(arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated.
+	* config/arc/arc.opt (mcmem): New option.
+	* config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative,
+	supply length for r/m alternative.
+	(*extendqisi2_ac): Likewise.
+	(*extendhisi2_i): Add r/Uex alternative, supply length for r/m and
+	r/Uex alternative.
+	(movqi_insn): Add r/Ucm and Ucm/?Rac alternatives.
+	(movhi_insn): Likewise.
+	(movsi_insn): Add r/Ucm,Ucm/w alternatives.
+	(*zero_extendqihi2_i): Add r/Ucm alternative.
+	(*zero_extendqisi2_ac): Likewise.
+	(*zero_extendhisi2_i): Likewise.
+	* config/arc/constraints.md (Uex): New memory constraint.
+	(Ucm): New define_constraint.
+	* config/arc/predicates.md (long_immediate_loadstore_operand):
+	Return 0 for MEM with cmem_address address.
+	(cmem_address_0): New predicates.
+	(cmem_address_1): Likewise.
+	(cmem_address_2): Likewise.
+	(cmem_address): Likewise.
+
 2016-03-01  Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Andrew Burgess  <andrew.burgess@embecosm.com>
 
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 35bb44a..25ff693 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1784,6 +1784,8 @@ arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
     case LABEL_REF :
     case SYMBOL_REF :
     case CONST :
+      if (TARGET_NPS400_CMEM && cmem_address (addr, SImode))
+	return 0;
       /* Most likely needs a LIMM.  */
       return COSTS_N_INSNS (1);
 
@@ -4258,6 +4260,24 @@ arc_encode_section_info (tree decl, rtx rtl, int first)
 
       SYMBOL_REF_FLAGS (symbol) = flags;
     }
+  else if (TREE_CODE (decl) == VAR_DECL)
+    {
+      rtx symbol = XEXP (rtl, 0);
+
+      tree attr = (TREE_TYPE (decl) != error_mark_node
+		   ? DECL_ATTRIBUTES (decl) : NULL_TREE);
+
+      tree sec_attr = lookup_attribute ("section", attr);
+      if (sec_attr)
+	{
+	  const char *sec_name
+	    = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
+	  if (strcmp (sec_name, ".cmem") == 0
+	      || strcmp (sec_name, ".cmem_shared") == 0
+	      || strcmp (sec_name, ".cmem_private") == 0)
+          SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
+	}
+    }
 }
 
 /* This is how to output a definition of an internal numbered label where
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 1cb59ec..28c3ef1 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_SHORT_CALL	(SYMBOL_FLAG_MACH_DEP << 0)
 #define SYMBOL_FLAG_MEDIUM_CALL	(SYMBOL_FLAG_MACH_DEP << 1)
 #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
+#define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
 
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)	\
@@ -317,6 +318,10 @@ along with GCC; see the file COPYING3.  If not see
 #define UNALIGNED_ACCESS_DEFAULT 0
 #endif
 
+#ifndef TARGET_NPS400_CMEM_DEFAULT
+#define TARGET_NPS400_CMEM_DEFAULT 0
+#endif
+
 /* Target machine storage layout.  */
 
 /* We want zero_extract to mean the same
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 99e8e30..33e6dee 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -611,8 +611,8 @@
 ; The iscompact attribute allows the epilogue expander to know for which
 ; insns it should lengthen the return insn.
 (define_insn "*movqi_insn"
-  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m")
-	(match_operand:QI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))]
+  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,w,Rcq,S,!*x,r,r,Ucm,m,???m")
+	(match_operand:QI 1 "move_src_operand"  "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))]
   "register_operand (operands[0], QImode)
    || register_operand (operands[1], QImode)"
   "@
@@ -626,13 +626,15 @@
    ldb%? %0,%1%&
    stb%? %1,%0%&
    ldb%? %0,%1%&
+   xldb%U1 %0,%1
    ldb%U1%V1 %0,%1
+   xstb%U0 %1,%0
    stb%U0%V0 %1,%0
    stb%U0%V0 %1,%0"
-  [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false")
-   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,load,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false,false,false")
+   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 (define_expand "movhi"
   [(set (match_operand:HI 0 "move_dest_operand" "")
@@ -641,8 +643,8 @@
   "if (prepare_move_operands (operands, HImode)) DONE;")
 
 (define_insn "*movhi_insn"
-  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc")
-	(match_operand:HI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,  ?i,?i,T,Rcq,m,c,?Rac,i"))]
+  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,Rcq#q,w,Rcq,S,r,r,Ucm,m,???m,VUsc")
+	(match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,?i,T,Rcq,Ucm,m,?Rac,c,?Rac,i"))]
   "register_operand (operands[0], HImode)
    || register_operand (operands[1], HImode)
    || (CONSTANT_P (operands[1])
@@ -661,14 +663,16 @@
    mov%? %0,%S1
    ld%_%? %0,%1%&
    st%_%? %1,%0%&
+   xld%_%U1 %0,%1
    ld%_%U1%V1 %0,%1
+   xst%_%U0 %1,%0
    st%_%U0%V0 %1,%0
    st%_%U0%V0 %1,%0
    st%_%U0%V0 %S1,%0"
-  [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false")
-   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false")
+   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 (define_expand "movsi"
   [(set (match_operand:SI 0 "move_dest_operand" "")
@@ -687,8 +691,8 @@
 ; insns it should lengthen the return insn.
 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
 (define_insn "*movsi_insn"
-  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,m,???m,VUsc")
-	(match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,m,c,?Rac,C32"))]
+  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
+	(match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)
    || (CONSTANT_P (operands[1])
@@ -713,17 +717,19 @@
    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
    ld%? %0,%1%&		;15
-   ld%U1%V1 %0,%1	;16
-   st%U0%V0 %1,%0       ;17
-   st%U0%V0 %1,%0       ;18
-   st%U0%V0 %S1,%0      ;19"
-  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false")
+   xld%U1 %0,%1         ;16
+   ld%U1%V1 %0,%1	;17
+   xst%U0 %1,%0         ;18
+   st%U0%V0 %1,%0       ;19
+   st%U0%V0 %1,%0       ;20
+   st%U0%V0 %S1,%0      ;21"
+  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
    ; Use default length for iscompact to allow for COND_EXEC.  But set length
    ; of Crr to 4.
-   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8")
-   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
+   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
+   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 ;; Sometimes generated by the epilogue code.  We don't want to
 ;; recognize these addresses in general, because the limm is costly,
@@ -1450,18 +1456,19 @@
 
 
 (define_insn "*zero_extendqihi2_i"
-  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
-	(zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
+  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
+	(zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
   ""
   "@
    extb%? %0,%1%&
    extb%? %0,%1%&
    bmsk%? %0,%1,7
    extb %0,%1
+   xldb%U1 %0,%1
    ldb%U1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load")
-   (set_attr "iscompact" "maybe,true,false,false,false")
-   (set_attr "predicable" "no,no,yes,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no")])
 
 (define_expand "zero_extendqihi2"
   [(set (match_operand:HI 0 "dest_reg_operand" "")
@@ -1471,8 +1478,8 @@
 )
 
 (define_insn "*zero_extendqisi2_ac"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
-	(zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
+	(zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
   ""
   "@
    extb%? %0,%1%&
@@ -1481,10 +1488,11 @@
    extb %0,%1
    ldb%? %0,%1%&
    ldb%? %0,%1%&
+   xldb%U1 %0,%1
    ldb%U1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load,load,load")
-   (set_attr "iscompact" "maybe,true,false,false,true,true,false")
-   (set_attr "predicable" "no,no,yes,no,no,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
 
 (define_expand "zero_extendqisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
@@ -1494,8 +1502,8 @@
 )
 
 (define_insn "*zero_extendhisi2_i"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
-	(zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
+	(zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,Ucm,m")))]
   ""
   "@
    ext%_%? %0,%1%&
@@ -1504,10 +1512,11 @@
    ext%_ %0,%1
    ld%_%? %0,%1%&
    ld%_%U1 %0,%1
+   * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
    ld%_%U1%V1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load,load,load")
-   (set_attr "iscompact" "maybe,true,false,false,true,false,false")
-   (set_attr "predicable" "no,no,yes,no,no,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
 
 
 (define_expand "zero_extendhisi2"
@@ -1520,15 +1529,17 @@
 ;; Sign extension instructions.
 
 (define_insn "*extendqihi2_i"
-  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
-	(sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
+  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
+	(sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
   ""
   "@
    sexb%? %0,%1%&
    sexb %0,%1
+   ldb.x%U1 %0,%1
    ldb.x%U1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,*,8")])
 
 
 (define_expand "extendqihi2"
@@ -1539,15 +1550,17 @@
 )
 
 (define_insn "*extendqisi2_ac"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
-	(sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
+	(sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
   ""
   "@
    sexb%? %0,%1%&
    sexb %0,%1
+   ldb.x%U1 %0,%1
    ldb.x%U1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,*,8")])
 
 (define_expand "extendqisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
@@ -1557,15 +1570,17 @@
 )
 
 (define_insn "*extendhisi2_i"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
-	(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
+	(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
   ""
   "@
    sex%_%? %0,%1%&
    sex%_ %0,%1
+   ld%_.x%U1%V1 %0,%1
    ld%_.x%U1%V1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,4,8")])
 
 (define_expand "extendhisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 55a5b32..4816238 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -457,6 +457,10 @@ Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
 EnumValue
 Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
 
+mcmem
+Target Report Var(TARGET_NPS400_CMEM) Init(TARGET_NPS400_CMEM_DEFAULT) Condition(ARC_NPS400)
+Enable use of NPS400 xld/xst extension.
+
 munaligned-access
 Target Report Var(unaligned_access) Init(UNALIGNED_ACCESS_DEFAULT) Condition(ARC_NPS400)
 Enable unaligned word and halfword accesses to packed data.
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index b6954ad..409e7d6 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -269,6 +269,13 @@
   (and (match_code "mem")
        (match_test "compact_store_memory_operand (op, VOIDmode)")))
 
+(define_memory_constraint "Uex"
+  "@internal
+   A valid memory operand for limm-free extend instructions"
+  (and (match_code "mem")
+       (match_test "!cmem_address (XEXP (op, 0), SImode)")
+       (not (match_operand 0 "long_immediate_loadstore_operand"))))
+
 ; Don't use define_memory_constraint here as the relocation patching
 ; for small data symbols only works within a ld/st instruction and
 ; define_memory_constraint may result in the address being calculated
@@ -303,6 +310,12 @@
        (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
        (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")))
 
+(define_constraint "Ucm"
+  "@internal
+  cmem access"
+  (and (match_code "mem")
+       (match_test "TARGET_NPS400_CMEM && cmem_address (XEXP (op, 0), VOIDmode)")))
+
 ;; General constraints
 
 (define_constraint "Cbr"
@@ -430,4 +443,3 @@
 (define_memory_constraint "ATO"
   "A memory with only a base register"
   (match_operand 0 "mem_noofs_operand"))
-
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index 85bbf84..fdfef4f 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -123,6 +123,8 @@
   int size = GET_MODE_SIZE (GET_MODE (op));
 
   op = XEXP (op, 0);
+  if (TARGET_NPS400_CMEM && cmem_address (op, SImode))
+    return 0;
   switch (GET_CODE (op))
     {
     case SYMBOL_REF :
@@ -806,3 +808,20 @@
 (define_predicate "double_register_operand"
   (ior (match_test "even_register_operand (op, mode)")
        (match_test "arc_double_register_operand (op, mode)")))
+
+(define_predicate "cmem_address_0"
+  (and (match_code "symbol_ref")
+       (match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_CMEM")))
+
+(define_predicate "cmem_address_1"
+  (and (match_code "plus")
+       (match_test "cmem_address_0 (XEXP (op, 0), SImode)")))
+
+(define_predicate "cmem_address_2"
+  (and (match_code "const")
+       (match_test "cmem_address_1 (XEXP (op, 0), SImode)")))
+
+(define_predicate "cmem_address"
+  (ior (match_operand:SI 0 "cmem_address_0")
+       (match_operand:SI 0 "cmem_address_1")
+       (match_operand:SI 0 "cmem_address_2")))
diff --git a/gcc/testsuite/ChangeLog.NPS400 b/gcc/testsuite/ChangeLog.NPS400
index b49dc1a..bc5e68c 100644
--- a/gcc/testsuite/ChangeLog.NPS400
+++ b/gcc/testsuite/ChangeLog.NPS400
@@ -1,3 +1,16 @@
+2013-08-09  Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* gcc.target/arc/cmem-1.c: New file.
+	* gcc.target/arc/cmem-2.c: New file.
+	* gcc.target/arc/cmem-3.c: New file.
+	* gcc.target/arc/cmem-4.c: New file.
+	* gcc.target/arc/cmem-5.c: New file.
+	* gcc.target/arc/cmem-6.c: New file.
+	* gcc.target/arc/cmem-7.c: New file.
+	* gcc.target/arc/cmem-ld.inc: New file.
+	* gcc.target/arc/cmem-st.inc: New file.
+
 2016-02-03  Joern Rennecke  <joern.rennecke@embecosm.com>
 
 	* gcc.target/arc/setmem-1.c: New file.
diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c b/gcc/testsuite/gcc.target/arc/cmem-1.c
new file mode 100644
index 0000000..34c6d0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c b/gcc/testsuite/gcc.target/arc/cmem-2.c
new file mode 100644
index 0000000..994b8b0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c b/gcc/testsuite/gcc.target/arc/cmem-3.c
new file mode 100644
index 0000000..875d2f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c b/gcc/testsuite/gcc.target/arc/cmem-4.c
new file mode 100644
index 0000000..983780e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c b/gcc/testsuite/gcc.target/arc/cmem-5.c
new file mode 100644
index 0000000..ea5594a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-5.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c b/gcc/testsuite/gcc.target/arc/cmem-6.c
new file mode 100644
index 0000000..fdcd1a6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-6.c
@@ -0,0 +1,10 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c b/gcc/testsuite/gcc.target/arc/cmem-7.c
new file mode 100644
index 0000000..1e74876
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-7.c
@@ -0,0 +1,26 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-mcmem" } */
+
+struct some_struct
+{
+  unsigned char a;
+};
+
+unsigned char other_func (unsigned char);
+
+unsigned char
+some_function ()
+{
+  static struct some_struct ss __attribute__ ((section (".cmem")));
+  static struct some_struct tt;
+
+  ss.a = other_func (ss.a);
+  tt.a = other_func (tt.a);
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler "xldb \[^\n\]*@ss" } } */
+/* { dg-final { scan-assembler "xstb \[^\n\]*@ss" } } */
+/* { dg-final { scan-assembler-not "xldb \[^\n\]*@tt" } } */
+/* { dg-final { scan-assembler-not "xstb \[^\n\]*@tt" } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-ld.inc b/gcc/testsuite/gcc.target/arc/cmem-ld.inc
new file mode 100644
index 0000000..7b51bb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-ld.inc
@@ -0,0 +1,16 @@
+
+struct foo_type
+{
+  unsigned int a;
+  unsigned short b;
+  unsigned char c;
+};
+
+struct foo_type foo __attribute__ ((section (".cmem")));
+
+unsigned int
+f ()
+{
+  unsigned int tmp = foo.a + foo.b + foo.c;
+  return tmp;
+}
diff --git a/gcc/testsuite/gcc.target/arc/cmem-st.inc b/gcc/testsuite/gcc.target/arc/cmem-st.inc
new file mode 100644
index 0000000..30aeace
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-st.inc
@@ -0,0 +1,18 @@
+
+struct foo_type
+{
+  unsigned int a;
+  unsigned short b;
+  unsigned char c;
+};
+
+struct foo_type foo CMEM_SECTION_ATTR
+
+int
+f ()
+{
+  foo.a = 3;
+  foo.b = 2;
+  foo.c = 1;
+  return 0;
+}
-- 
2.6.4

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

* [PATCH 04/10] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
  2016-03-04 13:25 ` [PATCH 01/10] gcc: Add support for mellanox nps400 arc variant Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 09/10] gcc/arc: Add an nps400 specific testcase Andrew Burgess
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

In the load*_update instructions the constraint 'rI' was being used,
which would accept either a register or a signed 12 bit constant.  The
problem is that the 32-bit form of ld with update only takes a signed
9-bit immediate.  As such, some ld instructions could be generated that
would, when assembled be 64-bit long, however, GCC believed them to be
32-bit long.  This error in the length would cause problems during
branch shortening.

The store*_update have the same restrictions on immediate size, however,
the patterns for these instructions already only accept 9-bit
immediates, and so should be safe.

gcc/ChangeLog:

	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
	constraint with separate 'r' and 'Cm2' constraints.
	(*load_zeroextendqisi_update): Likewise.
	(*load_signextendqisi_update): Likewise.
	(*loadhi_update): Likewise.
	(*load_zeroextendhisi_update): Likewise.
	(*load_signextendhisi_update): Likewise.
	(*loadsi_update): Likewise.
	(*loadsf_update): Likewise.
---
 gcc/ChangeLog.NPS400  | 12 +++++++
 gcc/config/arc/arc.md | 96 +++++++++++++++++++++++++--------------------------
 2 files changed, 60 insertions(+), 48 deletions(-)

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 716e413..71463df 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,15 @@
+2016-02-01  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
+	constraint with separate 'r' and 'Cm2' constraints.
+	(*load_zeroextendqisi_update): Likewise.
+	(*load_signextendqisi_update): Likewise.
+	(*loadhi_update): Likewise.
+	(*load_zeroextendhisi_update): Likewise.
+	(*load_signextendhisi_update): Likewise.
+	(*loadsi_update): Likewise.
+	(*loadsf_update): Likewise.
+
 2015-09-08  Andrew Burgess  <andrew.burgess@embecosm.com>
 	    Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Noam Camus  <noamca@mellanox.com>
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 4193d26..99e8e30 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -1151,40 +1151,40 @@
 
 ;; Note: loadqi_update has no 16-bit variant
 (define_insn "*loadqi_update"
-  [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:QI 3 "dest_reg_operand" "=r,r,r")
         (match_operator:QI 4 "any_mem_operand"
-         [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-                   (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+         [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+                   (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ldb.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*load_zeroextendqisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(zero_extend:SI (match_operator:QI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ldb.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*load_signextendqisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(sign_extend:SI (match_operator:QI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ldb.x.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storeqi_update"
   [(set (match_operator:QI 4 "any_mem_operand"
@@ -1201,41 +1201,41 @@
 ;; ??? pattern may have to be re-written
 ;; Note: no 16-bit variant for this pattern
 (define_insn "*loadhi_update"
-  [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:HI 3 "dest_reg_operand" "=r,r,r")
 	(match_operator:HI 4 "any_mem_operand"
-	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+	           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld%_.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*load_zeroextendhisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(zero_extend:SI (match_operator:HI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld%_.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 ;; Note: no 16-bit variant for this instruction
 (define_insn "*load_signextendhisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(sign_extend:SI (match_operator:HI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld%_.x.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storehi_update"
   [(set (match_operator:HI 4 "any_mem_operand"
@@ -1251,16 +1251,16 @@
 
 ;; No 16-bit variant for this instruction pattern
 (define_insn "*loadsi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(match_operator:SI 4 "any_mem_operand"
-	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+	           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storesi_update"
   [(set (match_operator:SI 4 "any_mem_operand"
@@ -1275,16 +1275,16 @@
    (set_attr "length" "4")])
 
 (define_insn "*loadsf_update"
-  [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SF 3 "dest_reg_operand" "=r,r,r")
 	(match_operator:SF 4 "any_mem_operand"
-	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+	           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storesf_update"
   [(set (match_operator:SF 4 "any_mem_operand"
-- 
2.6.4

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

* [PATCH 02/10] gcc/arc: Add -munaligned-access option for nps400
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (8 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 07/10] gcc/arc: Add nps400 bitops support Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-04-21 11:39 ` [PATCHv2 3/7] gcc/arc: convert some constraints to define_constraint Andrew Burgess
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

New option for nps400 arc (-munaligned-access) that allows GCC to
generate unaligned accesses, the option is off by default.  Turning this
option on will update the value for STRICT_ALIGNMENT.

gcc/ChangeLog:

	* config/arc/arc.h (ARC_NPS400): Define if not already defined.
	(UNALIGNED_ACCESS_DEFAULT): Define, if not already defined.
	(STRICT_ALIGNMENT): Make use of unaligned_access var.
	* config/arc/arc.c (arc_expand_movmem): Take STRICT_ALIGNMENT into
	account.
	* config/arc/arc.opt: (munaligned-access): New option.
	* config/arc/t-nps400: Add munaligned-access to the multilib list.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/setmem-1.c: New file.
	* gcc.target/arc/setmem-2.c: New file.
	* gcc.target/arc/setmem-3.c: New file.
	* gcc.target/arc/setmem-4.c: New file.
---
 gcc/ChangeLog.NPS400                    | 11 +++++++++++
 gcc/config/arc/arc.c                    |  4 ++--
 gcc/config/arc/arc.h                    | 19 +++++++++++++++----
 gcc/config/arc/arc.opt                  |  4 ++++
 gcc/config/arc/t-nps400                 |  2 +-
 gcc/testsuite/ChangeLog.NPS400          |  6 ++++++
 gcc/testsuite/gcc.target/arc/setmem-1.c | 13 +++++++++++++
 gcc/testsuite/gcc.target/arc/setmem-2.c | 18 ++++++++++++++++++
 gcc/testsuite/gcc.target/arc/setmem-3.c | 13 +++++++++++++
 gcc/testsuite/gcc.target/arc/setmem-4.c | 18 ++++++++++++++++++
 10 files changed, 101 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/ChangeLog.NPS400
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/setmem-4.c

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 286f2dd..0281640 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,14 @@
+2016-02-02  Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Andrew Burgess  <andrew.burgess@embecosm.com>
+
+	* config/arc/arc.h (ARC_NPS400): Define if not already defined.
+	(UNALIGNED_ACCESS_DEFAULT): Define, if not already defined.
+	(STRICT_ALIGNMENT): Make use of unaligned_access var.
+	* config/arc/arc.c (arc_expand_movmem): Take STRICT_ALIGNMENT into
+	account.
+	* config/arc/arc.opt: (munaligned-access): New option.
+	* config/arc/t-nps400: Add munaligned-access to the multilib list.
+
 2016-02-01  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * config.gcc: Add support for arc*-mellanox-* nps400 targets.
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index d60db50..35bb44a 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -7137,7 +7137,7 @@ arc_expand_movmem (rtx *operands)
   HOST_WIDE_INT size;
   int align = INTVAL (operands[3]);
   unsigned n_pieces;
-  int piece = align;
+  int piece = STRICT_ALIGNMENT ? align : 4;
   rtx store[2];
   rtx tmpx[2];
   int i;
@@ -7146,7 +7146,7 @@ arc_expand_movmem (rtx *operands)
     return false;
   size = INTVAL (operands[2]);
   /* move_by_pieces_ninsns is static, so we can't use it.  */
-  if (align >= 4)
+  if (align >= 4 || !STRICT_ALIGNMENT)
     {
       if (TARGET_LL64)
 	n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 21c049f..1cb59ec 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -62,6 +62,10 @@ along with GCC; see the file COPYING3.  If not see
 #undef ASM_APP_OFF
 #undef CC1_SPEC
 
+#ifndef ARC_NPS400
+#define ARC_NPS400 0
+#endif
+
 /* Names to predefine in the preprocessor for this target machine.  */
 #define TARGET_CPU_CPP_BUILTINS()	\
  do {					\
@@ -309,6 +313,10 @@ along with GCC; see the file COPYING3.  If not see
 #define MULTILIB_DEFAULTS { "mARC700" }
 #endif
 
+#ifndef UNALIGNED_ACCESS_DEFAULT
+#define UNALIGNED_ACCESS_DEFAULT 0
+#endif
+
 /* Target machine storage layout.  */
 
 /* We want zero_extract to mean the same
@@ -416,10 +424,13 @@ if (GET_MODE_CLASS (MODE) == MODE_INT		\
 
 /* Set this nonzero if move instructions will actually fail to work
    when given unaligned data.  */
-/* On the ARC the lower address bits are masked to 0 as necessary.  The chip
-   won't croak when given an unaligned address, but the insn will still fail
-   to produce the correct result.  */
-#define STRICT_ALIGNMENT 1
+/* On most ARC cores the lower address bits are masked to 0 as necessary,
+   the chip won't croak when given an unaligned address, but the insn will
+   still fail to produce the correct result.  */
+/* The NPS400 ARC variant supports unaligned access.  Although not without
+   cost, this is still fast enough that we can justify keeping
+   SLOW_UNALIGNED_ACCESS off.  */
+#define STRICT_ALIGNMENT (!unaligned_access)
 
 /* Layout of source language data types.  */
 
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 2227b75..f8e062c 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -456,3 +456,7 @@ Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
 
 EnumValue
 Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+
+munaligned-access
+Target Report Var(unaligned_access) Init(UNALIGNED_ACCESS_DEFAULT) Condition(ARC_NPS400)
+Enable unaligned word and halfword accesses to packed data.
diff --git a/gcc/config/arc/t-nps400 b/gcc/config/arc/t-nps400
index e332e24..2d96b78 100644
--- a/gcc/config/arc/t-nps400
+++ b/gcc/config/arc/t-nps400
@@ -18,4 +18,4 @@
 # with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-MULTILIB_OPTIONS=
+MULTILIB_OPTIONS=munaligned-access
diff --git a/gcc/testsuite/ChangeLog.NPS400 b/gcc/testsuite/ChangeLog.NPS400
new file mode 100644
index 0000000..b49dc1a
--- /dev/null
+++ b/gcc/testsuite/ChangeLog.NPS400
@@ -0,0 +1,6 @@
+2016-02-03  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+	* gcc.target/arc/setmem-1.c: New file.
+	* gcc.target/arc/setmem-2.c: New file.
+	* gcc.target/arc/setmem-3.c: New file.
+	* gcc.target/arc/setmem-4.c: New file.
diff --git a/gcc/testsuite/gcc.target/arc/setmem-1.c b/gcc/testsuite/gcc.target/arc/setmem-1.c
new file mode 100644
index 0000000..926974e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/setmem-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -munaligned-access" } */
+
+extern void *memcpy (void *, const void *, __SIZE_TYPE__);
+
+void
+f (char *d)
+{
+  static const char a[] = "abcdefghijklmnopqrstuvwxyz";
+  memcpy (d, a, 20);
+}
+/* { dg-final { scan-assembler-not "stb"  } } */
+/* { dg-final { scan-assembler-not "memcpy"  } } */
diff --git a/gcc/testsuite/gcc.target/arc/setmem-2.c b/gcc/testsuite/gcc.target/arc/setmem-2.c
new file mode 100644
index 0000000..a034fbd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/setmem-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -munaligned-access" } */
+
+extern void *memcpy (void *, const void *, __SIZE_TYPE__);
+
+void
+f (char *d)
+{
+  static const char a[] =
+    {
+      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+      'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+      'u', 'v', 'w', 'x', 'y', 'z',
+    };
+  memcpy (d, a, 20);
+}
+/* { dg-final { scan-assembler-not "stb"  } } */
+/* { dg-final { scan-assembler-not "memcpy"  } } */
diff --git a/gcc/testsuite/gcc.target/arc/setmem-3.c b/gcc/testsuite/gcc.target/arc/setmem-3.c
new file mode 100644
index 0000000..660d924
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/setmem-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -munaligned-access" } */
+
+extern void *memcpy (void *, const void *, __SIZE_TYPE__);
+
+void
+f (char *d)
+{
+  const char a[26] = "abcdefghijklmnopqrstuvwxyz";
+  memcpy (d, a, 20);
+}
+/* { dg-final { scan-assembler-not "stb"  } } */
+/* { dg-final { scan-assembler-not "memcpy"  } } */
diff --git a/gcc/testsuite/gcc.target/arc/setmem-4.c b/gcc/testsuite/gcc.target/arc/setmem-4.c
new file mode 100644
index 0000000..b5c1ee6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/setmem-4.c
@@ -0,0 +1,18 @@
+/* { dg-do compile { target arc*-mellanox-* } } */
+/* { dg-options "-O2 -munaligned-access" } */
+
+extern void *memcpy (void *, const void *, __SIZE_TYPE__);
+
+void
+f (char *d)
+{
+  const char a[26] =
+    {
+      'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+      'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+      'u', 'v', 'w', 'x', 'y', 'z',
+    };
+  memcpy (d, a, 20);
+}
+/* { dg-final { scan-assembler-not "stb" } } */
+/* { dg-final { scan-assembler-not "memcpy" } } */
-- 
2.6.4

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

* [PATCH 03/10] gcc/arc: generate jump tables in code section for nps400
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (3 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 08/10] gcc/arc: Mask integer 'L' operands to 32-bit Andrew Burgess
@ 2016-03-04 13:26 ` Andrew Burgess
  2016-03-04 13:26 ` [PATCH 05/10] gcc/arc: convert some constraints to define_constraint Andrew Burgess
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-03-04 13:26 UTC (permalink / raw)
  To: gcc-patches; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

When code runs from section loaded into fast memory we do not want it to
use rodata section from a slow memory for any jump tables.  This commit
turns on CASE_VECTOR_PC_RELATIVE by default for NPS400 targets, which in
turn turns on JUMP_TABLES_IN_TEXT_SECTION, which will place the jump
tables into the code section.

As a later optimisation we could be smarter about this, only turning on
inline jump tables when the code section is not the default code
section (.text), which we assume is not loaded into fast memory.

gcc/ChangeLog:

	* config/arc/arc.opt (TARGET_CASE_VECTOR_PC_RELATIVE): Default on
	for NPS400.
---
 gcc/ChangeLog.NPS400   | 7 +++++++
 gcc/config/arc/arc.opt | 2 +-
 2 files changed, 8 insertions(+), 1 deletion(-)

diff --git a/gcc/ChangeLog.NPS400 b/gcc/ChangeLog.NPS400
index 0281640..716e413 100644
--- a/gcc/ChangeLog.NPS400
+++ b/gcc/ChangeLog.NPS400
@@ -1,3 +1,10 @@
+2015-09-08  Andrew Burgess  <andrew.burgess@embecosm.com>
+	    Joern Rennecke  <joern.rennecke@embecosm.com>
+	    Noam Camus  <noamca@mellanox.com>
+
+	* config/arc/arc.opt (TARGET_CASE_VECTOR_PC_RELATIVE): Default on
+	for NPS400.
+
 2016-02-02  Joern Rennecke  <joern.rennecke@embecosm.com>
 	    Andrew Burgess  <andrew.burgess@embecosm.com>
 
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index f8e062c..55a5b32 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -283,7 +283,7 @@ Target Var(TARGET_BBIT_PEEPHOLE)
 Enable bbit peephole2.
 
 mcase-vector-pcrel
-Target Var(TARGET_CASE_VECTOR_PC_RELATIVE)
+Target Var(TARGET_CASE_VECTOR_PC_RELATIVE) Init(ARC_NPS400 != 0)
 Use pc-relative switch case tables - this enables case table shortening.
 
 mcompact-casesi
-- 
2.6.4

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

* [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (10 preceding siblings ...)
  2016-04-21 11:39 ` [PATCHv2 3/7] gcc/arc: convert some constraints to define_constraint Andrew Burgess
@ 2016-04-21 11:39 ` Andrew Burgess
  2016-04-28 15:31   ` Joern Wolfgang Rennecke
  2016-04-21 11:39 ` [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns Andrew Burgess
                   ` (5 subsequent siblings)
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:39 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

This new iteration of the previous version is largely the same except
that I now no longer use configure time options to build in support
for nps400.  Instead support controlled with a -mcpu=nps400 command
line switch.  This change was made to mirror a similar change that was
requested when I pushed nps400 support upstream into binutils.

Most of the instructions added in this series are now in mainline
binutils, there are a few outstanding (<10) which I will return too
after this patch, but if anyone is super keen then there's a version
of binutils with full nps400 support on github:
     https://github.com/EZchip/binutils

However, all of the nps400 specific tests are compile only, so a
binutils with full nps400 support should not be required in order to
test these changes.

Thanks,
Andrew

---

Andrew Burgess (7):
  gcc/arc: Add support for nps400 cpu type.
  gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns
  gcc/arc: convert some constraints to define_constraint
  gcc/arc: Add support for nps400 cmem xld/xst instructions
  gcc/arc: Add nps400 bitops support
  gcc/arc: Mask integer 'L' operands to 32-bit
  gcc/arc: Add an nps400 specific testcase

 gcc/ChangeLog.NPS400                      | 104 ++++++
 gcc/common/config/arc/arc-common.c        |   4 +
 gcc/config/arc/arc-opts.h                 |   1 +
 gcc/config/arc/arc.c                      |  68 +++-
 gcc/config/arc/arc.h                      |  23 +-
 gcc/config/arc/arc.md                     | 567 +++++++++++++++++++++++-------
 gcc/config/arc/arc.opt                    |  18 +
 gcc/config/arc/constraints.md             |  86 ++++-
 gcc/config/arc/predicates.md              |  19 +
 gcc/testsuite/ChangeLog.NPS400            |  43 +++
 gcc/testsuite/gcc.target/arc/cmem-1.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-2.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-3.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-4.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-5.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-6.c     |  10 +
 gcc/testsuite/gcc.target/arc/cmem-7.c     |  26 ++
 gcc/testsuite/gcc.target/arc/cmem-ld.inc  |  16 +
 gcc/testsuite/gcc.target/arc/cmem-st.inc  |  18 +
 gcc/testsuite/gcc.target/arc/extzv-1.c    |  11 +
 gcc/testsuite/gcc.target/arc/insv-1.c     |  21 ++
 gcc/testsuite/gcc.target/arc/insv-2.c     |  18 +
 gcc/testsuite/gcc.target/arc/movb-1.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-2.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-3.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-4.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-5.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb_cl-1.c  |   9 +
 gcc/testsuite/gcc.target/arc/movb_cl-2.c  |  11 +
 gcc/testsuite/gcc.target/arc/movbi_cl-1.c |   9 +
 gcc/testsuite/gcc.target/arc/movh_cl-1.c  |  27 ++
 gcc/testsuite/gcc.target/arc/movl-1.c     |  17 +
 gcc/testsuite/gcc.target/arc/nps400-1.c   |  23 ++
 33 files changed, 1109 insertions(+), 155 deletions(-)
 create mode 100644 gcc/ChangeLog.NPS400
 create mode 100644 gcc/testsuite/ChangeLog.NPS400
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-6.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-7.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-ld.inc
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-st.inc
 create mode 100644 gcc/testsuite/gcc.target/arc/extzv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movbi_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movh_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/nps400-1.c

-- 
2.6.4

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

* [PATCHv2 3/7] gcc/arc: convert some constraints to define_constraint
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (9 preceding siblings ...)
  2016-03-04 13:26 ` [PATCH 02/10] gcc/arc: Add -munaligned-access option for nps400 Andrew Burgess
@ 2016-04-21 11:39 ` Andrew Burgess
  2016-04-28 17:16   ` Joern Wolfgang Rennecke
  2016-04-21 11:39 ` [PATCHv2 0/7] ARC: Add support for nps400 variant Andrew Burgess
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:39 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

The define_memory_constraint allows for the address operand to be
reloaded into a base register.  However, for the constraints 'Us<' and
'Us>', which are used for matching 'push' and 'pop' instructions moving
the address into a base register is not helpful.  The constraints then
should be define_constraint, not define_memory_constraint.

Similarly the Usd constraint, used for generating small data area memory
accesses, can't have its operand loaded into a register as the
relocation for small data area symbols only works within ld/st
instructions.

gcc/ChangeLog:

	* config/arc/constraints.md (Usd): Convert to define_constraint.
	(Us<): Likewise.
	(Us>): Likewise.
---
 gcc/ChangeLog.NPS400          |  7 +++++++
 gcc/config/arc/constraints.md | 18 +++++++++++-------
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index 668b60a..b6954ad 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -269,11 +269,15 @@
   (and (match_code "mem")
        (match_test "compact_store_memory_operand (op, VOIDmode)")))
 
-(define_memory_constraint "Usd"
-  "@internal
-   A valid _small-data_ memory operand for ARCompact instructions"
-  (and (match_code "mem")
-       (match_test "compact_sda_memory_operand (op, VOIDmode)")))
+; Don't use define_memory_constraint here as the relocation patching
+; for small data symbols only works within a ld/st instruction and
+; define_memory_constraint may result in the address being calculated
+; into a register first.
+(define_constraint "Usd"
+   "@internal
+    A valid _small-data_ memory operand for ARCompact instructions"
+   (and (match_code "mem")
+        (match_test "compact_sda_memory_operand (op, VOIDmode)")))
 
 (define_memory_constraint "Usc"
   "@internal
@@ -283,7 +287,7 @@
 ;; ??? the assembler rejects stores of immediates to small data.
        (match_test "!compact_sda_memory_operand (op, VOIDmode)")))
 
-(define_memory_constraint "Us<"
+(define_constraint "Us<"
   "@internal
    Stack pre-decrement"
   (and (match_code "mem")
@@ -291,7 +295,7 @@
        (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
        (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")))
 
-(define_memory_constraint "Us>"
+(define_constraint "Us>"
   "@internal
    Stack post-increment"
   (and (match_code "mem")
-- 
2.6.4

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

* [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (11 preceding siblings ...)
  2016-04-21 11:39 ` [PATCHv2 0/7] ARC: Add support for nps400 variant Andrew Burgess
@ 2016-04-21 11:39 ` Andrew Burgess
  2016-04-28 17:07   ` Joern Wolfgang Rennecke
  2016-04-21 11:40 ` [PATCHv2 5/7] gcc/arc: Add nps400 bitops support Andrew Burgess
                   ` (4 subsequent siblings)
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:39 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

In the load*_update instructions the constraint 'rI' was being used,
which would accept either a register or a signed 12 bit constant.  The
problem is that the 32-bit form of ld with update only takes a signed
9-bit immediate.  As such, some ld instructions could be generated that
would, when assembled be 64-bit long, however, GCC believed them to be
32-bit long.  This error in the length would cause problems during
branch shortening.

The store*_update have the same restrictions on immediate size, however,
the patterns for these instructions already only accept 9-bit
immediates, and so should be safe.

gcc/ChangeLog:

	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
	constraint with separate 'r' and 'Cm2' constraints.
	(*load_zeroextendqisi_update): Likewise.
	(*load_signextendqisi_update): Likewise.
	(*loadhi_update): Likewise.
	(*load_zeroextendhisi_update): Likewise.
	(*load_signextendhisi_update): Likewise.
	(*loadsi_update): Likewise.
	(*loadsf_update): Likewise.
---
 gcc/ChangeLog.NPS400  | 12 +++++++
 gcc/config/arc/arc.md | 96 +++++++++++++++++++++++++--------------------------
 2 files changed, 60 insertions(+), 48 deletions(-)

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 4193d26..99e8e30 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -1151,40 +1151,40 @@
 
 ;; Note: loadqi_update has no 16-bit variant
 (define_insn "*loadqi_update"
-  [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:QI 3 "dest_reg_operand" "=r,r,r")
         (match_operator:QI 4 "any_mem_operand"
-         [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-                   (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+         [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+                   (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ldb.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*load_zeroextendqisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(zero_extend:SI (match_operator:QI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ldb.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*load_signextendqisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(sign_extend:SI (match_operator:QI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ldb.x.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storeqi_update"
   [(set (match_operator:QI 4 "any_mem_operand"
@@ -1201,41 +1201,41 @@
 ;; ??? pattern may have to be re-written
 ;; Note: no 16-bit variant for this pattern
 (define_insn "*loadhi_update"
-  [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:HI 3 "dest_reg_operand" "=r,r,r")
 	(match_operator:HI 4 "any_mem_operand"
-	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+	           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld%_.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*load_zeroextendhisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(zero_extend:SI (match_operator:HI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=r,r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld%_.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 ;; Note: no 16-bit variant for this instruction
 (define_insn "*load_signextendhisi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(sign_extend:SI (match_operator:HI 4 "any_mem_operand"
-			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+			           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))])))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld%_.x.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storehi_update"
   [(set (match_operator:HI 4 "any_mem_operand"
@@ -1251,16 +1251,16 @@
 
 ;; No 16-bit variant for this instruction pattern
 (define_insn "*loadsi_update"
-  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SI 3 "dest_reg_operand" "=r,r,r")
 	(match_operator:SI 4 "any_mem_operand"
-	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+	           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storesi_update"
   [(set (match_operator:SI 4 "any_mem_operand"
@@ -1275,16 +1275,16 @@
    (set_attr "length" "4")])
 
 (define_insn "*loadsf_update"
-  [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
+  [(set (match_operand:SF 3 "dest_reg_operand" "=r,r,r")
 	(match_operator:SF 4 "any_mem_operand"
-	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
-   (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
+	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0")
+	           (match_operand:SI 2 "nonmemory_operand" "r,Cm2,Cal"))]))
+   (set (match_operand:SI 0 "dest_reg_operand" "=w,w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
   "ld.a%V4 %3,[%0,%S2]"
-  [(set_attr "type" "load,load")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "load,load,load")
+   (set_attr "length" "4,4,8")])
 
 (define_insn "*storesf_update"
   [(set (match_operator:SF 4 "any_mem_operand"
-- 
2.6.4

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

* [PATCHv2 7/7] gcc/arc: Add an nps400 specific testcase
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (13 preceding siblings ...)
  2016-04-21 11:40 ` [PATCHv2 5/7] gcc/arc: Add nps400 bitops support Andrew Burgess
@ 2016-04-21 11:40 ` Andrew Burgess
  2016-04-28 19:14   ` Joern Wolfgang Rennecke
  2016-04-21 11:40 ` [PATCHv2 4/7] gcc/arc: Add support for nps400 cmem xld/xst instructions Andrew Burgess
                   ` (2 subsequent siblings)
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:40 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

This test case triggered a bug caused by VOIDmode not being handled in
proper_comparison_operator, this problem was fixed with a commit on
2016-01-27 by Claudiu Zissulescu, adding this test case for coverage.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/nps400-1.c: New file.
---
 gcc/testsuite/ChangeLog.NPS400          |  4 ++++
 gcc/testsuite/gcc.target/arc/nps400-1.c | 23 +++++++++++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/arc/nps400-1.c

diff --git a/gcc/testsuite/gcc.target/arc/nps400-1.c b/gcc/testsuite/gcc.target/arc/nps400-1.c
new file mode 100644
index 0000000..f3d6271
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/nps400-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mq-class -mbitops -munaligned-access -mcmem -O2 -fno-strict-aliasing" } */
+
+enum npsdp_mem_space_type {
+  NPSDP_EXTERNAL_MS = 1
+};
+struct npsdp_ext_addr {
+  struct {
+    struct {
+      enum npsdp_mem_space_type mem_type : 1;
+      unsigned msid : 5;
+    };
+  };
+  char user_space[];
+} a;
+char b;
+void fn1() {
+  ((struct npsdp_ext_addr *)a.user_space)->mem_type = NPSDP_EXTERNAL_MS;
+  ((struct npsdp_ext_addr *)a.user_space)->msid =
+      ((struct npsdp_ext_addr *)a.user_space)->mem_type ? 1 : 10;
+  while (b)
+    ;
+}
-- 
2.6.4

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

* [PATCHv2 6/7] gcc/arc: Mask integer 'L' operands to 32-bit
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (15 preceding siblings ...)
  2016-04-21 11:40 ` [PATCHv2 4/7] gcc/arc: Add support for nps400 cmem xld/xst instructions Andrew Burgess
@ 2016-04-21 11:40 ` Andrew Burgess
  2016-04-28 19:09   ` Joern Wolfgang Rennecke
  2016-04-21 11:40 ` [PATCHv2 1/7] gcc/arc: Add support for nps400 cpu type Andrew Burgess
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:40 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

When formatting 'L' operands (least significant word) only print
32-bits, don't sign extend to 64-bits.

This commit could really be applied directly to the current GCC trunk,
however, the only test I have for this issue right now relies on the
nps400 bitops support.

gcc/ChangeLog:

	* config/arc/arc.c (arc_print_operand): Print integer 'L' operands
	as 32-bits.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/movh_cl-1.c: New file.
---
 gcc/ChangeLog.NPS400                     |  6 ++++++
 gcc/config/arc/arc.c                     | 10 ++++------
 gcc/testsuite/ChangeLog.NPS400           |  4 ++++
 gcc/testsuite/gcc.target/arc/movh_cl-1.c | 27 +++++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/movh_cl-1.c

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 72a0825..b7b8516 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -3181,18 +3181,16 @@ arc_print_operand (FILE *file, rtx x, int code)
       else if (GET_CODE (x) == CONST_INT
 	       || GET_CODE (x) == CONST_DOUBLE)
 	{
-	  rtx first, second;
+	  rtx first, second, word;
 
 	  split_double (x, &first, &second);
 
 	  if((WORDS_BIG_ENDIAN) == 0)
-	      fprintf (file, "0x%08" PRIx64,
-		       code == 'L' ? INTVAL (first) : INTVAL (second));
+	    word = (code == 'L' ? first : second);
 	  else
-	      fprintf (file, "0x%08" PRIx64,
-		       code == 'L' ? INTVAL (second) : INTVAL (first));
-
+	    word = (code == 'L' ? second : first);
 
+	  fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
 	  }
       else
 	output_operand_lossage ("invalid operand to %%H/%%L code");
diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
new file mode 100644
index 0000000..220cd9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct thing
+{
+  union
+  {
+    int raw;
+    struct
+    {
+      unsigned a : 1;
+      unsigned b : 1;
+    };
+  };
+};
+
+extern void func (int);
+
+void
+blah ()
+{
+  struct thing xx;
+  xx.a = xx.b = 1;
+  func (xx.raw);
+}
+
+/* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
-- 
2.6.4

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

* [PATCHv2 5/7] gcc/arc: Add nps400 bitops support
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (12 preceding siblings ...)
  2016-04-21 11:39 ` [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns Andrew Burgess
@ 2016-04-21 11:40 ` Andrew Burgess
  2016-04-28 18:50   ` Joern Wolfgang Rennecke
  2016-04-21 11:40 ` [PATCHv2 7/7] gcc/arc: Add an nps400 specific testcase Andrew Burgess
                   ` (3 subsequent siblings)
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:40 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

Add support for nps400 bit operation instructions.  There's a new flag
-mbitops that turns this feature on.  There are new instructions, some
changes to existing instructions, a new register class to support the
new instructions, and some new expand and peephole optimisations.

gcc/ChangeLog:

	* config/arc/arc.c (arc_conditional_register_usage): Take
	TARGET_RRQ_CLASS into account.
	(arc_print_operand): Support printing 'p' and 's' operands.
	* config/arc/arc.h (TARGET_NPS_BITOPS_DEFAULT): Provide default
	as 0.
	(TARGET_RRQ_CLASS): Define.
	(IS_POWEROF2_OR_0_P): Define.
	* config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi
	alternatives.
	(*tst_movb): New define_insn.
	(*tst): Avoid recognition if it could prevent '*tst_movb'
	combination; replace c/CnL with c/Chs alternative.
	(*tst_bitfield_tst): New define_insn.
	(*tst_bitfield_asr): New define_insn.
	(*tst_bitfield): New define_insn.
	(andsi3_i): Add Rrq variant.
	(extzv): New define_expand.
	(insv): New define_expand.
	(*insv_i): New define_insn.
	(*movb): New define_insn.
	(*movb_signed): New define_insn.
	(*movb_high): New define_insn.
	(*movb_high_signed): New define_insn.
	(*movb_high_signed + 1): New define_split pattern.
	(*mrgb): New define_insn.
	(*mrgb + 1): New define_peephole2 pattern.
	(*mrgb + 2): New define_peephole2 pattern.
	* config/arc/arc.opt (mbitops): New option for nps400, uses
	TARGET_NPS_BITOPS_DEFAULT.
	* config/arc/constraints.md (q): Make register class conditional.
	(Rrq): New register constraint.
	(Chs): New constraint.
	(Clo): New constraint.
	(Chi): New constraint.
	(Cbf): New constraint.
	(Cbn): New constraint.
	(C18): New constraint.
	(Cbi): New constraint.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/extzv-1.c: New file.
	* gcc.target/arc/insv-1.c: New file.
	* gcc.target/arc/insv-2.c: New file.
	* gcc.target/arc/movb-1.c: New file.
	* gcc.target/arc/movb-2.c: New file.
	* gcc.target/arc/movb-3.c: New file.
	* gcc.target/arc/movb-4.c: New file.
	* gcc.target/arc/movb-5.c: New file.
	* gcc.target/arc/movb_cl-1.c: New file.
	* gcc.target/arc/movb_cl-2.c: New file.
	* gcc.target/arc/movbi_cl-1.c: New file.
	* gcc.target/arc/movl-1.c: New file.
---
 gcc/ChangeLog.NPS400                      |  42 ++++
 gcc/config/arc/arc.c                      |  33 ++-
 gcc/config/arc/arc.h                      |   9 +
 gcc/config/arc/arc.md                     | 382 ++++++++++++++++++++++++++----
 gcc/config/arc/arc.opt                    |   4 +
 gcc/config/arc/constraints.md             |  58 ++++-
 gcc/testsuite/ChangeLog.NPS400            |  16 ++
 gcc/testsuite/gcc.target/arc/extzv-1.c    |  11 +
 gcc/testsuite/gcc.target/arc/insv-1.c     |  21 ++
 gcc/testsuite/gcc.target/arc/insv-2.c     |  18 ++
 gcc/testsuite/gcc.target/arc/movb-1.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-2.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-3.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-4.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb-5.c     |  13 +
 gcc/testsuite/gcc.target/arc/movb_cl-1.c  |   9 +
 gcc/testsuite/gcc.target/arc/movb_cl-2.c  |  11 +
 gcc/testsuite/gcc.target/arc/movbi_cl-1.c |   9 +
 gcc/testsuite/gcc.target/arc/movl-1.c     |  17 ++
 19 files changed, 648 insertions(+), 57 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/extzv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/insv-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movbi_cl-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/movl-1.c

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 890a1a5..72a0825 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1376,7 +1376,8 @@ arc_conditional_register_usage (void)
     {
       if (i < 29)
 	{
-	  if (TARGET_Q_CLASS && ((i <= 3) || ((i >= 12) && (i <= 15))))
+	  if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
+	      && ((i <= 3) || ((i >= 12) && (i <= 15))))
 	    arc_regno_reg_class[i] = ARCOMPACT16_REGS;
 	  else
 	    arc_regno_reg_class[i] = GENERAL_REGS;
@@ -1393,12 +1394,12 @@ arc_conditional_register_usage (void)
 	arc_regno_reg_class[i] = NO_REGS;
     }
 
-  /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS has not been activated.  */
+  /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
+     has not been activated.  */
+  if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
+    CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
   if (!TARGET_Q_CLASS)
-    {
-      CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
-      CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
-    }
+    CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
 
   gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
 
@@ -2940,6 +2941,8 @@ static int output_scaled = 0;
     'Z': log2(x+1)-1
     'z': log2
     'M': log2(~x)
+    'p': bit Position of lsb
+    's': size of bit field
     '#': condbranch delay slot suffix
     '*': jump delay slot suffix
     '?' : nonjump-insn suffix for conditional execution or short instruction
@@ -2990,6 +2993,24 @@ arc_print_operand (FILE *file, rtx x, int code)
 
       return;
 
+    case 'p':
+      if (GET_CODE (x) == CONST_INT)
+	fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
+      else
+	output_operand_lossage ("invalid operand to %%p code");
+      return;
+
+    case 's':
+      if (GET_CODE (x) == CONST_INT)
+	{
+	  HOST_WIDE_INT i = INTVAL (x);
+	  HOST_WIDE_INT s = exact_log2 (i & -i);
+	  fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
+	}
+      else
+	output_operand_lossage ("invalid operand to %%s code");
+      return;
+
     case '#' :
       /* Conditional branches depending on condition codes.
 	 Note that this is only for branches that were known to depend on
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 5ac4115..48d472d 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -318,10 +318,18 @@ along with GCC; see the file COPYING3.  If not see
 #define UNALIGNED_ACCESS_DEFAULT 0
 #endif
 
+#ifndef TARGET_NPS_BITOPS_DEFAULT
+#define TARGET_NPS_BITOPS_DEFAULT 0
+#endif
+
 #ifndef TARGET_NPS_CMEM_DEFAULT
 #define TARGET_NPS_CMEM_DEFAULT 0
 #endif
 
+/* Enable the RRQ instruction alternatives.  */
+
+#define TARGET_RRQ_CLASS TARGET_NPS_BITOPS
+
 /* Target machine storage layout.  */
 
 /* We want zero_extract to mean the same
@@ -1022,6 +1030,7 @@ extern int arc_initial_elimination_offset(int from, int to);
 
 /* Is the argument a const_int rtx, containing an exact power of 2 */
 #define  IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X))
+#define  IS_POWEROF2_OR_0_P(X) (! ( (X) & ((X) - 1)))
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 33e6dee..9c9ca03 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -691,8 +691,8 @@
 ; insns it should lengthen the return insn.
 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
 (define_insn "*movsi_insn"
-  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
-	(match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
+  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,w,w,w,w,???w,?w,w,Rcq#q,w,Rcq,S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
+	(match_operand:SI 1 "move_src_operand"  "cL,cP,Rcq#q,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)
    || (CONSTANT_P (operands[1])
@@ -707,29 +707,32 @@
    mov%? %0,%1		;3
    mov%? %0,%1		;4
    ror %0,((%1*2+1) & 0x3f) ;5
-   mov%? %0,%1		;6
-   add %0,%S1		;7
+   movl.cl %0,%1       ;6
+   movh.cl %0,%L1>>16  ;7
+   * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\";
+   mov%? %0,%1		;9
+   add %0,%S1		;10
    * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\";
-   mov%? %0,%S1%&	;9
-   mov%? %0,%S1		;10
-   ld%? %0,%1%&		;11
-   st%? %1,%0%&		;12
+   mov%? %0,%S1%&	;12
+   mov%? %0,%S1		;13
+   ld%? %0,%1%&		;14
+   st%? %1,%0%&		;15
    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
-   ld%? %0,%1%&		;15
-   xld%U1 %0,%1         ;16
-   ld%U1%V1 %0,%1	;17
-   xst%U0 %1,%0         ;18
-   st%U0%V0 %1,%0       ;19
-   st%U0%V0 %1,%0       ;20
-   st%U0%V0 %S1,%0      ;21"
-  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
+   ld%? %0,%1%&		;18
+   xld%U1 %0,%1                ;19
+   ld%U1%V1 %0,%1	;20
+   xst%U0 %1,%0                ;21
+   st%U0%V0 %1,%0       ;22
+   st%U0%V0 %1,%0       ;23
+   st%U0%V0 %S1,%0      ;24"
+  [(set_attr "type" "move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
    ; Use default length for iscompact to allow for COND_EXEC.  But set length
    ; of Crr to 4.
-   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
-   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
+   (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
+   (set_attr "predicable" "yes,no,yes,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 ;; Sometimes generated by the epilogue code.  We don't want to
 ;; recognize these addresses in general, because the limm is costly,
@@ -800,6 +803,24 @@
    (set_attr "cond" "set_zn")
    (set_attr "length" "4")])
 
+; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees
+; a c/???Cal/X alternative, so we say it's c/???Cal/c instead,
+; even if we don't need the clobber.
+(define_insn_and_split "*tst_movb"
+  [(set
+     (match_operand 0 "cc_register" "")
+     (match_operator 4 "zn_compare_operator"
+       [(and:SI
+	  (match_operand:SI 1 "register_operand"  "%Rcq,Rcq, c,  c,  c,  c,Rrq,  3,  c")
+	  (match_operand:SI 2 "nonmemory_operand"  "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal"))
+	(const_int 0)]))
+   (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))]
+  "TARGET_NPS_BITOPS"
+  "movb.f.cl %3,%1,%p2,%p2,%s2"
+  "reload_completed
+   && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)"
+  [(set (match_dup 0) (match_dup 4))])
+
 (define_insn "*tst"
   [(set
      (match_operand 0 "cc_register" "")
@@ -808,12 +829,14 @@
 	  (match_operand:SI 1 "register_operand"
 	   "%Rcq,Rcq, c, c, c,  c,  c,  c")
 	  (match_operand:SI 2 "nonmemory_operand"
-	   " Rcq,C0p,cI,cL,C1p,Ccp,CnL,Cal"))
+	   " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal"))
 	(const_int 0)]))]
-  "(register_operand (operands[1], SImode)
-    && nonmemory_operand (operands[2], SImode))
-   || (memory_operand (operands[1], SImode)
-       && satisfies_constraint_Cux (operands[2]))"
+  "reload_completed
+   || !satisfies_constraint_Cbf (operands[2])
+   || satisfies_constraint_C0p (operands[2])
+   || satisfies_constraint_I (operands[2])
+   || satisfies_constraint_C1p (operands[2])
+   || satisfies_constraint_Chs (operands[2])"
   "*
     switch (which_alternative)
     {
@@ -826,17 +849,79 @@
     case 5:
       return \"bclr%?.f 0,%1,%M2%&\";
     case 6:
-      return \"bic%?.f 0,%1,%n2-1\";
+      return \"asr.f 0,%1,%p2\";
     default:
       gcc_unreachable ();
     }
   "
   [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false")
-   (set_attr "type" "compare")
+   (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare")
    (set_attr "length" "*,*,4,4,4,4,4,8")
    (set_attr "predicable" "no,yes,no,yes,no,no,no,yes")
    (set_attr "cond" "set_zn")])
 
+; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract,
+; combine will do that and not try the AND.
+
+; It would take 66 constraint combinations to describe the zero_extract
+; constants that are covered by the 12-bit signed constant for tst
+; (excluding the ones that are better done by mov or btst).
+; so we rather use an extra pattern for tst;
+; since this is about constants, reload shouldn't care.
+(define_insn "*tst_bitfield_tst"
+  [(set (match_operand:CC_ZN 0 "cc_set_register" "")
+	(match_operator 4 "zn_compare_operator"
+	  [(zero_extract:SI
+	     (match_operand:SI 1 "register_operand"  "c")
+	     (match_operand:SI 2 "const_int_operand" "n")
+	     (match_operand:SI 3 "const_int_operand" "n"))
+	   (const_int 0)]))]
+  "INTVAL (operands[2]) > 1
+   && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11
+       || (INTVAL (operands[3]) <= 11
+	   && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))"
+  "tst %1,(1<<%2)-1<<%3"
+  [(set_attr "type" "compare")
+   (set_attr "cond" "set_zn")
+   (set_attr "length" "4")])
+
+; Likewise for asr.f.
+(define_insn "*tst_bitfield_asr"
+  [(set (match_operand:CC_ZN 0 "cc_set_register" "")
+	(match_operator 4 "zn_compare_operator"
+	  [(zero_extract:SI
+	     (match_operand:SI 1 "register_operand"  "c")
+	     (match_operand:SI 2 "const_int_operand" "n")
+	     (match_operand:SI 3 "const_int_operand" "n"))
+	   (const_int 0)]))]
+  "INTVAL (operands[2]) > 1
+   && INTVAL (operands[3]) + INTVAL (operands[2]) == 32"
+  "asr.f 0,%1,%3"
+  [(set_attr "type" "shift")
+   (set_attr "cond" "set_zn")
+   (set_attr "length" "4")])
+
+(define_insn "*tst_bitfield"
+  [(set (match_operand:CC_ZN 0 "cc_set_register" "")
+	(match_operator 5 "zn_compare_operator"
+	  [(zero_extract:SI
+	     (match_operand:SI 1 "register_operand" "%Rcqq,c,  c,Rrq,c")
+	     (match_operand:SI 2 "const_int_operand"    "N,N,  n,Cbn,n")
+	     (match_operand:SI 3 "const_int_operand"    "n,n,C_0,Cbn,n"))
+	   (const_int 0)]))
+   (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))]
+  ""
+  "@
+   btst%? %1,%3
+   btst %1,%3
+   bmsk.f 0,%1,%2-1
+   movb.f.cl %4,%1,%3,%3,%2
+   and.f 0,%1,((1<<%2)-1)<<%3"
+  [(set_attr "iscompact" "maybe,false,false,false,false")
+   (set_attr "type" "compare,compare,compare,shift,compare")
+   (set_attr "cond" "set_zn")
+   (set_attr "length" "*,4,4,4,8")])
+
 (define_insn "*commutative_binary_comparison"
   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
 	(match_operator:CC_ZN 5 "zn_compare_operator"
@@ -2947,30 +3032,40 @@
      operands[1] = arc_rewrite_small_data (operands[1]);")
 
 (define_insn "andsi3_i"
-  [(set (match_operand:SI 0 "dest_reg_operand"          "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,  w,  w,  w,  w,w,Rcw,  w,  W")
-	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,   0,   0,Rcqq,  0,  c,  0,  0,  0,  0,  c,  c,  c,  c,0,  0,  c,  o")
-		(match_operand:SI 2 "nonmemory_operand" " Rcqq,  0, C1p, Ccp, Cux, cL,  0,C1p,Ccp,CnL,  I, Lc,C1p,Ccp,CnL,I,Cal,Cal,Cux")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,w,w,w,w,Rrq,w,Rcw,w,W")
+	(and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,0,0,Rcqq,0,c,0,0,0,0,c,c,c,c,Rrq,0,0,c,o")
+		(match_operand:SI 2 "nonmemory_operand" "Rcqq,0,C1p,Ccp,Cux,cL,0,C1p,Ccp,CnL,I,Lc,C1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))]
   "(register_operand (operands[1], SImode)
     && nonmemory_operand (operands[2], SImode))
    || (memory_operand (operands[1], SImode)
        && satisfies_constraint_Cux (operands[2]))"
-  "*
 {
   switch (which_alternative)
     {
-    case 0: case 5: case 10: case 11: case 15: case 16: case 17:
-      return \"and%? %0,%1,%2%&\";
+    case 0: case 5: case 10: case 11: case 16: case 17: case 18:
+      return "and%? %0,%1,%2%&";
     case 1: case 6:
-      return \"and%? %0,%2,%1%&\";
+      return "and%? %0,%2,%1%&";
     case 2: case 7: case 12:
-      return \"bmsk%? %0,%1,%Z2%&\";
+      return "bmsk%? %0,%1,%Z2%&";
     case 3: case 8: case 13:
-      return \"bclr%? %0,%1,%M2%&\";
+      return "bclr%? %0,%1,%M2%&";
     case 4:
       return (INTVAL (operands[2]) == 0xff
-	      ? \"extb%? %0,%1%&\" : \"ext%_%? %0,%1%&\");
+	      ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&");
     case 9: case 14: return \"bic%? %0,%1,%n2-1\";
-    case 18:
+    case 15:
+      return "movb.cl %0,%1,%p2,%p2,%s2";
+
+    case 19:
+      const char *tmpl;
+
+      if (satisfies_constraint_Ucm (operands[1]))
+	tmpl = (INTVAL (operands[2]) == 0xff
+		? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1");
+      else
+	tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1";
+
       if (TARGET_BIG_ENDIAN)
 	{
 	  rtx xop[2];
@@ -2978,21 +3073,19 @@
 	  xop[0] = operands[0];
 	  xop[1] = adjust_address (operands[1], QImode,
 				   INTVAL (operands[2]) == 0xff ? 3 : 2);
-	  output_asm_insn (INTVAL (operands[2]) == 0xff
-			   ? \"ldb %0,%1\" : \"ld%_ %0,%1\",
-			   xop);
-	  return \"\";
+	  output_asm_insn (tmpl, xop);
+	  return "";
 	}
-      return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ld%_ %0,%1\";
+      return tmpl;
     default:
       gcc_unreachable ();
     }
-}"
-  [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
-   (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load")
-   (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
-   (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no")
-   (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
+}
+  [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false")
+   (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load")
+   (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*")
+   (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no")
+   (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")])
 
 ; combiner splitter, pattern found in ldtoa.c .
 ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1
@@ -5642,7 +5735,6 @@
   [(set_attr "length" "4")
    (set_attr "type" "misc")])
 
-
 ;; FPU/FPX expands
 
 ;;add
@@ -5785,6 +5877,196 @@
    gcc_unreachable ();
  ")
 
+(define_expand "extzv"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "")
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" "")))]
+  "TARGET_NPS_BITOPS")
+
+; We need a sanity check in the instuction predicate because combine
+; will throw any old rubbish at us and see what sticks.
+(define_insn "*extzv_i"
+  [(set (match_operand:SI 0 "register_operand" "=Rrq")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq")
+			 (match_operand:SI 2 "const_int_operand" "n")
+			 (match_operand:SI 3 "const_int_operand" "n")))]
+  "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32"
+  "movb.cl %0,%1,0,%3,%2"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_expand "insv"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
+			 (match_operand:SI 1 "const_int_operand" "")
+			 (match_operand:SI 2 "const_int_operand" ""))
+	(match_operand:SI 3 "nonmemory_operand" ""))]
+  "TARGET_NPS_BITOPS"
+{
+  int size = INTVAL (operands[1]);
+
+  if (size != 1 && size != 2 && size != 4 && size != 8)
+    operands[3] = force_reg (SImode, operands[3]);
+})
+
+(define_insn "*insv_i"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq")
+			 (match_operand:SI 1 "const_int_operand" "C18,n")
+			 (match_operand:SI 2 "const_int_operand" "n,n"))
+	(match_operand:SI 3 "nonmemory_operand" "P,Rrq"))]
+  "TARGET_NPS_BITOPS
+   && (register_operand (operands[3], SImode)
+       || satisfies_constraint_C18 (operands[1]))"
+  "@
+   movbi %0,%0,%3,%2,%1
+   movb %0,%0,%3,%2,0,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_insn "*movb"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
+			 (match_dup 1)
+			 (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS_BITOPS"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_insn "*movb_signed"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq")
+			 (match_dup 1)
+			 (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS_BITOPS"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_insn "*movb_high"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
+		     (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS_BITOPS
+   && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+; N.B.: when processing signed bitfields that fit in the top half of
+; a word, gcc will use a narrow sign extending load, and in this case
+; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8)
+(define_insn "*movb_high_signed"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq")
+		     (match_operand:SI 4 "const_int_operand" "n")))]
+  "TARGET_NPS_BITOPS
+   && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32"
+  "movb %0,%0,%3,%2,%4,%1"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "")
+			   (match_operand:SI 2 "const_int_operand" ""))
+		(subreg:SI (match_operand 3 "") 0)))]
+  "TARGET_NPS_BITOPS
+   && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2])
+   && !reg_overlap_mentioned_p (operands[0], operands[1])"
+  [(set (match_dup 0) (zero_extend:SI (match_dup 3)))
+   (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2))
+	(match_dup 1))]
+  "operands[4] = GEN_INT (32 - INTVAL (operands[2]));")
+
+(define_insn "*mrgb"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq")
+			 (match_operand:SI 1 "const_int_operand" "n")
+			 (match_operand:SI 2 "const_int_operand" "n"))
+	(zero_extract:SI (match_dup 0) (match_dup 1)
+			 (match_operand:SI 3 "const_int_operand" "n")))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 4 "const_int_operand" "n")
+			 (match_operand:SI 5 "const_int_operand" "n"))
+	(zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq")
+			 (match_dup 4)
+			 (match_operand:SI 7 "const_int_operand" "n")))]
+  "TARGET_NPS_BITOPS"
+{
+  output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands);
+  /* The ;%? updates the known unalignment.  */
+  return arc_short_long (insn, ";%?", "nop_s");
+}
+  [(set_attr "type" "shift")
+   (set_attr "length" "6")
+   (set_attr "iscompact" "true")])
+
+;; combine fumbles combination of two movb patterns, and then the
+;; combination is rejected by combinable_i3pat.
+;; Thus, we can only use a peephole2 to combine two such insns.
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "register_operand" ""))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" ""))
+	(zero_extract:SI (match_dup 1)
+			 (match_dup 2)
+			 (match_operand:SI 4 "const_int_operand" "")))
+   (match_operand 9) ; unrelated insn scheduled here
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 5 "const_int_operand" "")
+			 (match_operand:SI 6 "const_int_operand" ""))
+	(zero_extract:SI (match_operand:SI 7 "register_operand" "")
+			 (match_dup 5)
+			 (match_operand:SI 8 "const_int_operand" "")))]
+  "TARGET_NPS_BITOPS
+   // Check that the second movb doesn't clobber an input of the extra insn.
+   && !reg_overlap_mentioned_p (operands[0], operands[9])
+   // And vice versa.
+   && !reg_set_p (operands[0], operands[9])
+   && !reg_set_p (operands[7], operands[9])"
+  [(set (match_dup 0) (match_dup 1))
+   (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
+		   (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))
+	      (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2))
+		   (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))])
+   (match_dup 9)])
+
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+	(match_operand:SI 1 "register_operand" ""))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 2 "const_int_operand" "")
+			 (match_operand:SI 3 "const_int_operand" ""))
+	(zero_extract:SI (match_dup 1)
+			 (match_dup 2)
+			 (match_operand:SI 4 "const_int_operand" "")))
+   (set (match_dup 1) (match_operand 8))
+   (set (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 5 "const_int_operand" "")
+			 (match_operand:SI 6 "const_int_operand" ""))
+	(zero_extract:SI (match_dup 1) (match_dup 5)
+			 (match_operand:SI 7 "const_int_operand" "")))]
+  "TARGET_NPS_BITOPS
+   && !reg_overlap_mentioned_p (operands[0], operands[8])"
+  [(set (match_dup 0) (match_dup 1))
+   (set (match_dup 1) (match_dup 8))
+   (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3))
+		   (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4)))
+	      (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6))
+		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
+   (match_dup 1)])
+
 ;; include the arc-FPX instructions
 (include "fpx.md")
 
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 19d4c21..2b7db61 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -463,6 +463,10 @@ Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
 EnumValue
 Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
 
+mbitops
+Target Report Var(TARGET_NPS_BITOPS) Init(TARGET_NPS_BITOPS_DEFAULT)
+Enable use of NPS400 bit operations.
+
 mcmem
 Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT)
 Enable use of NPS400 xld/xst extension.
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index c2992c9..f30572c 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -66,10 +66,18 @@
    Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30},
    @code{blink}:@code{r31},")
 
-(define_register_constraint "q" "ARCOMPACT16_REGS"
+(define_register_constraint "q" "TARGET_Q_CLASS ? ARCOMPACT16_REGS : NO_REGS"
   "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3},
    @code{r12}-@code{r15}")
 
+; NPS400 bitfield instructions require registers from the r0-r3,r12-r15
+; range, and thus we need a register class and constraint that works
+; independently of size optimization.
+(define_register_constraint
+ "Rrq" "TARGET_RRQ_CLASS ? ARCOMPACT16_REGS : NO_REGS"
+  "Registers usable in NPS400 bitfield instructions: @code{r0}-@code{r3},
+   @code{r12}-@code{r15}")
+
 (define_register_constraint "e" "AC16_BASE_REGS"
   "Registers usable as base-regs of memory addresses in ARCompact 16-bit memory
    instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}")
@@ -236,12 +244,60 @@
   (and (match_code "const_int")
        (match_test "ival == 0xff || ival == 0xffff")))
 
+(define_constraint "Chs"
+ "@internal
+  constant for a highpart that can be checked with a shift (asr.f 0,rn,m)"
+  (and (match_code "const_int")
+       (match_test "IS_POWEROF2_P (-ival)")))
+
+(define_constraint "Clo"
+ "@internal
+  constant that fits into 16 lower bits, for movl"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS_BITOPS")
+       (match_test "(ival & ~0xffffU) == 0")))
+
+(define_constraint "Chi"
+ "@internal
+  constant that fits into 16 higher bits, for movh_i"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS_BITOPS")
+       (match_test "trunc_int_for_mode (ival >> 16, HImode) << 16 == ival")))
+
+(define_constraint "Cbf"
+ "@internal
+  a mask for a bit field, for AND using movb_i"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS_BITOPS")
+       (match_test "IS_POWEROF2_OR_0_P (ival + (ival & -ival))")))
+
+(define_constraint "Cbn"
+ "@internal
+  a constant integer, valid only if TARGET_NPS_BITOPS is true"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS_BITOPS")))
+
+(define_constraint "C18"
+ "@internal
+  1,2,4 or 8"
+  (and (match_code "const_int")
+       (match_test "ival == 1 || ival == 2 || ival == 4 || ival == 8")))
+
 (define_constraint "Crr"
  "@internal
   constant that can be loaded with ror b,u6"
   (and (match_code "const_int")
        (match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()")))
 
+(define_constraint "Cbi"
+ "@internal
+  constant that can be loaded with movbi.cl"
+  (and (match_code "const_int")
+       (match_test "TARGET_NPS_BITOPS")
+       (match_test "!ival
+		    || ((ival & 0xffffffffUL) >> exact_log2 (ival & -ival)
+			<= 0xff)")))
+
 ;; Floating-point constraints
 
 (define_constraint "G"
diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c b/gcc/testsuite/gcc.target/arc/extzv-1.c
new file mode 100644
index 0000000..242f522
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/extzv-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct foo { unsigned a: 3, b: 5, c: 24; };
+
+int
+f (struct foo i)
+{
+  return i.b;
+}
+/* { dg-final { scan-assembler "movb\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c b/gcc/testsuite/gcc.target/arc/insv-1.c
new file mode 100644
index 0000000..75d47e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/insv-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+/* ??? Irrespective of insn set, generated code for this is a mess.  */
+struct foo { unsigned a: 3, b: 8, c: 21; };
+
+struct foo
+f (struct foo i)
+{
+  i.b = 42;
+  return i;
+}
+
+struct foo
+g (struct foo i, int j)
+{
+  i.b = j;
+  return i;
+}
+/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
+/* { dg-final { scan-assembler "movb\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c b/gcc/testsuite/gcc.target/arc/insv-2.c
new file mode 100644
index 0000000..1652551
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/insv-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct foo { unsigned a: 3, b: 8, c: 21; } bar;
+
+void
+f (void)
+{
+  bar.b = 42;
+}
+
+void
+g (int j)
+{
+  bar.b = j;
+}
+/* { dg-final { scan-assembler "movbi\[ \t\]" } } */
+/* { dg-final { scan-assembler "movb\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
new file mode 100644
index 0000000..65d4ba4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct { unsigned a: 5, b: 8, c: 19; } foo;
+struct { unsigned a: 3, b: 8, c: 21; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
new file mode 100644
index 0000000..1ba9976
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct { unsigned a: 23, b: 9; } foo;
+struct { unsigned a: 23, b: 9; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c b/gcc/testsuite/gcc.target/arc/movb-3.c
new file mode 100644
index 0000000..0895154
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct { int a: 23, b: 9; } foo;
+struct { int a: 23, b: 9; } bar;
+
+void
+f (void)
+{
+  bar.a = foo.a;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *23" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *9, *9, *23" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c b/gcc/testsuite/gcc.target/arc/movb-4.c
new file mode 100644
index 0000000..89bf2c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct { int a: 13, b: 19; } foo;
+struct { int a: 13, b: 19; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *13, *13, *19" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *19" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
new file mode 100644
index 0000000..9dbe8a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb-5.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+struct { int a: 23, b: 9; } foo;
+struct { int a: 23, b: 9; } bar;
+
+void
+f (void)
+{
+  bar.b = foo.b;
+}
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
new file mode 100644
index 0000000..402250c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+int
+f (int i)
+{
+  return i & 0x0ffff000;
+}
+/* { dg-final { scan-assembler "movb\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
new file mode 100644
index 0000000..d2e5a94
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+extern void g (void);
+int
+f (int i)
+{
+  if (i & 0x0ffff000)
+    g ();
+}
+/* { dg-final { scan-assembler "movb\.f\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
new file mode 100644
index 0000000..3c457db
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+int
+f (int i)
+{
+  return 0x6e00;
+}
+/* { dg-final { scan-assembler "mov(bi|l)\.cl" } } */
diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c b/gcc/testsuite/gcc.target/arc/movl-1.c
new file mode 100644
index 0000000..f1f0130
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/movl-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */
+
+int
+f (void)
+{
+  return 0xd00d;
+}
+
+int
+g (void)
+{
+  return 0x7ff00000;
+}
+
+/* { dg-final { scan-assembler "movl\.cl\[ \t\]" } } */
+/* { dg-final { scan-assembler "movh\.cl\[ \t\]" } } */
-- 
2.6.4

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

* [PATCHv2 4/7] gcc/arc: Add support for nps400 cmem xld/xst instructions
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (14 preceding siblings ...)
  2016-04-21 11:40 ` [PATCHv2 7/7] gcc/arc: Add an nps400 specific testcase Andrew Burgess
@ 2016-04-21 11:40 ` Andrew Burgess
  2016-04-28 18:23   ` Joern Wolfgang Rennecke
  2016-04-21 11:40 ` [PATCHv2 6/7] gcc/arc: Mask integer 'L' operands to 32-bit Andrew Burgess
  2016-04-21 11:40 ` [PATCHv2 1/7] gcc/arc: Add support for nps400 cpu type Andrew Burgess
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:40 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

This commit adds support for NPS400 cmem memory sections.  Data to be
placed into cmem memory is placed into a section ".cmem",
".cmem_shared", or ".cmem_private".

There are restrictions on how instructions can be used to operate on
data held in cmem memory, this is reflected by the introduction of new
operand constraints (Uex/Ucm), and modifications to some instructions to
make use of these constraints.

gcc/ChangeLog:

	* config/arc/arc.h (SYMBOL_FLAG_CMEM): Define.
	(TARGET_NPS_CMEM_DEFAULT): Provide default definition.
	* config/arc/arc.c (arc_address_cost): Return 0 for cmem_address.
	(arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated.
	* config/arc/arc.opt (mcmem): New option.
	* config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative,
	supply length for r/m alternative.
	(*extendqisi2_ac): Likewise.
	(*extendhisi2_i): Add r/Uex alternative, supply length for r/m and
	r/Uex alternative.
	(movqi_insn): Add r/Ucm and Ucm/?Rac alternatives.
	(movhi_insn): Likewise.
	(movsi_insn): Add r/Ucm,Ucm/w alternatives.
	(*zero_extendqihi2_i): Add r/Ucm alternative.
	(*zero_extendqisi2_ac): Likewise.
	(*zero_extendhisi2_i): Likewise.
	* config/arc/constraints.md (Uex): New memory constraint.
	(Ucm): New define_constraint.
	* config/arc/predicates.md (long_immediate_loadstore_operand):
	Return 0 for MEM with cmem_address address.
	(cmem_address_0): New predicates.
	(cmem_address_1): Likewise.
	(cmem_address_2): Likewise.
	(cmem_address): Likewise.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/cmem-1.c: New file.
	* gcc.target/arc/cmem-2.c: New file.
	* gcc.target/arc/cmem-3.c: New file.
	* gcc.target/arc/cmem-4.c: New file.
	* gcc.target/arc/cmem-5.c: New file.
	* gcc.target/arc/cmem-6.c: New file.
	* gcc.target/arc/cmem-7.c: New file.
	* gcc.target/arc/cmem-ld.inc: New file.
	* gcc.target/arc/cmem-st.inc: New file.
---
 gcc/ChangeLog.NPS400                     |  28 ++++++++
 gcc/config/arc/arc.c                     |  20 ++++++
 gcc/config/arc/arc.h                     |   9 +++
 gcc/config/arc/arc.md                    | 115 +++++++++++++++++--------------
 gcc/config/arc/arc.opt                   |   8 +++
 gcc/config/arc/constraints.md            |  14 +++-
 gcc/config/arc/predicates.md             |  19 +++++
 gcc/testsuite/ChangeLog.NPS400           |  19 +++++
 gcc/testsuite/gcc.target/arc/cmem-1.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-2.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-3.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-4.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-5.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-6.c    |  10 +++
 gcc/testsuite/gcc.target/arc/cmem-7.c    |  26 +++++++
 gcc/testsuite/gcc.target/arc/cmem-ld.inc |  16 +++++
 gcc/testsuite/gcc.target/arc/cmem-st.inc |  18 +++++
 17 files changed, 301 insertions(+), 51 deletions(-)
 create mode 100644 gcc/testsuite/ChangeLog.NPS400
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-1.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-2.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-3.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-4.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-5.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-6.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-7.c
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-ld.inc
 create mode 100644 gcc/testsuite/gcc.target/arc/cmem-st.inc

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index ae8772e..890a1a5 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1789,6 +1789,8 @@ arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
     case LABEL_REF :
     case SYMBOL_REF :
     case CONST :
+      if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
+	return 0;
       /* Most likely needs a LIMM.  */
       return COSTS_N_INSNS (1);
 
@@ -4263,6 +4265,24 @@ arc_encode_section_info (tree decl, rtx rtl, int first)
 
       SYMBOL_REF_FLAGS (symbol) = flags;
     }
+  else if (TREE_CODE (decl) == VAR_DECL)
+    {
+      rtx symbol = XEXP (rtl, 0);
+
+      tree attr = (TREE_TYPE (decl) != error_mark_node
+		   ? DECL_ATTRIBUTES (decl) : NULL_TREE);
+
+      tree sec_attr = lookup_attribute ("section", attr);
+      if (sec_attr)
+	{
+	  const char *sec_name
+	    = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
+	  if (strcmp (sec_name, ".cmem") == 0
+	      || strcmp (sec_name, ".cmem_shared") == 0
+	      || strcmp (sec_name, ".cmem_private") == 0)
+          SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
+	}
+    }
 }
 
 /* This is how to output a definition of an internal numbered label where
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index f96bf0f..5ac4115 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 #define SYMBOL_FLAG_SHORT_CALL	(SYMBOL_FLAG_MACH_DEP << 0)
 #define SYMBOL_FLAG_MEDIUM_CALL	(SYMBOL_FLAG_MACH_DEP << 1)
 #define SYMBOL_FLAG_LONG_CALL	(SYMBOL_FLAG_MACH_DEP << 2)
+#define SYMBOL_FLAG_CMEM	(SYMBOL_FLAG_MACH_DEP << 3)
 
 /* Check if this symbol has a long_call attribute in its declaration */
 #define SYMBOL_REF_LONG_CALL_P(X)	\
@@ -313,6 +314,14 @@ along with GCC; see the file COPYING3.  If not see
 #define MULTILIB_DEFAULTS { "mARC700" }
 #endif
 
+#ifndef UNALIGNED_ACCESS_DEFAULT
+#define UNALIGNED_ACCESS_DEFAULT 0
+#endif
+
+#ifndef TARGET_NPS_CMEM_DEFAULT
+#define TARGET_NPS_CMEM_DEFAULT 0
+#endif
+
 /* Target machine storage layout.  */
 
 /* We want zero_extract to mean the same
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 99e8e30..33e6dee 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -611,8 +611,8 @@
 ; The iscompact attribute allows the epilogue expander to know for which
 ; insns it should lengthen the return insn.
 (define_insn "*movqi_insn"
-  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m")
-	(match_operand:QI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))]
+  [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,w,Rcq,S,!*x,r,r,Ucm,m,???m")
+	(match_operand:QI 1 "move_src_operand"  "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))]
   "register_operand (operands[0], QImode)
    || register_operand (operands[1], QImode)"
   "@
@@ -626,13 +626,15 @@
    ldb%? %0,%1%&
    stb%? %1,%0%&
    ldb%? %0,%1%&
+   xldb%U1 %0,%1
    ldb%U1%V1 %0,%1
+   xstb%U0 %1,%0
    stb%U0%V0 %1,%0
    stb%U0%V0 %1,%0"
-  [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false")
-   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,load,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false,false,false")
+   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 (define_expand "movhi"
   [(set (match_operand:HI 0 "move_dest_operand" "")
@@ -641,8 +643,8 @@
   "if (prepare_move_operands (operands, HImode)) DONE;")
 
 (define_insn "*movhi_insn"
-  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc")
-	(match_operand:HI 1 "move_src_operand"   "cL,cP,Rcq#q,cL,I,?Rac,  ?i,?i,T,Rcq,m,c,?Rac,i"))]
+  [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,Rcq#q,w,Rcq,S,r,r,Ucm,m,???m,VUsc")
+	(match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,?i,T,Rcq,Ucm,m,?Rac,c,?Rac,i"))]
   "register_operand (operands[0], HImode)
    || register_operand (operands[1], HImode)
    || (CONSTANT_P (operands[1])
@@ -661,14 +663,16 @@
    mov%? %0,%S1
    ld%_%? %0,%1%&
    st%_%? %1,%0%&
+   xld%_%U1 %0,%1
    ld%_%U1%V1 %0,%1
+   xst%_%U0 %1,%0
    st%_%U0%V0 %1,%0
    st%_%U0%V0 %1,%0
    st%_%U0%V0 %S1,%0"
-  [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false")
-   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*")])
+  [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false")
+   (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 (define_expand "movsi"
   [(set (match_operand:SI 0 "move_dest_operand" "")
@@ -687,8 +691,8 @@
 ; insns it should lengthen the return insn.
 ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc .
 (define_insn "*movsi_insn"
-  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,m,???m,VUsc")
-	(match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,m,c,?Rac,C32"))]
+  [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,  w,???w, ?w,  w,Rcq#q, w,Rcq,  S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc")
+	(match_operand:SI 1 "move_src_operand"  " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))]
   "register_operand (operands[0], SImode)
    || register_operand (operands[1], SImode)
    || (CONSTANT_P (operands[1])
@@ -713,17 +717,19 @@
    * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\");
    * return arc_short_long (insn, \"pop%? %0%&\",  \"ld%U1 %0,%1%&\");
    ld%? %0,%1%&		;15
-   ld%U1%V1 %0,%1	;16
-   st%U0%V0 %1,%0       ;17
-   st%U0%V0 %1,%0       ;18
-   st%U0%V0 %S1,%0      ;19"
-  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,store,store,store")
-   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false")
+   xld%U1 %0,%1         ;16
+   ld%U1%V1 %0,%1	;17
+   xst%U0 %1,%0         ;18
+   st%U0%V0 %1,%0       ;19
+   st%U0%V0 %1,%0       ;20
+   st%U0%V0 %S1,%0      ;21"
+  [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store")
+   (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false")
    ; Use default length for iscompact to allow for COND_EXEC.  But set length
    ; of Crr to 4.
-   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8")
-   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no")
-   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
+   (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8")
+   (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
+   (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
 
 ;; Sometimes generated by the epilogue code.  We don't want to
 ;; recognize these addresses in general, because the limm is costly,
@@ -1450,18 +1456,19 @@
 
 
 (define_insn "*zero_extendqihi2_i"
-  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r")
-	(zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))]
+  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r")
+	(zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))]
   ""
   "@
    extb%? %0,%1%&
    extb%? %0,%1%&
    bmsk%? %0,%1,7
    extb %0,%1
+   xldb%U1 %0,%1
    ldb%U1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load")
-   (set_attr "iscompact" "maybe,true,false,false,false")
-   (set_attr "predicable" "no,no,yes,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no")])
 
 (define_expand "zero_extendqihi2"
   [(set (match_operand:HI 0 "dest_reg_operand" "")
@@ -1471,8 +1478,8 @@
 )
 
 (define_insn "*zero_extendqisi2_ac"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r")
-	(zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r")
+	(zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))]
   ""
   "@
    extb%? %0,%1%&
@@ -1481,10 +1488,11 @@
    extb %0,%1
    ldb%? %0,%1%&
    ldb%? %0,%1%&
+   xldb%U1 %0,%1
    ldb%U1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load,load,load")
-   (set_attr "iscompact" "maybe,true,false,false,true,true,false")
-   (set_attr "predicable" "no,no,yes,no,no,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,true,true,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
 
 (define_expand "zero_extendqisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
@@ -1494,8 +1502,8 @@
 )
 
 (define_insn "*zero_extendhisi2_i"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r")
-	(zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r")
+	(zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,Ucm,m")))]
   ""
   "@
    ext%_%? %0,%1%&
@@ -1504,10 +1512,11 @@
    ext%_ %0,%1
    ld%_%? %0,%1%&
    ld%_%U1 %0,%1
+   * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\";
    ld%_%U1%V1 %0,%1"
-  [(set_attr "type" "unary,unary,unary,unary,load,load,load")
-   (set_attr "iscompact" "maybe,true,false,false,true,false,false")
-   (set_attr "predicable" "no,no,yes,no,no,no,no")])
+  [(set_attr "type" "unary,unary,unary,unary,load,load,load,load")
+   (set_attr "iscompact" "maybe,true,false,false,true,false,false,false")
+   (set_attr "predicable" "no,no,yes,no,no,no,no,no")])
 
 
 (define_expand "zero_extendhisi2"
@@ -1520,15 +1529,17 @@
 ;; Sign extension instructions.
 
 (define_insn "*extendqihi2_i"
-  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r")
-	(sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))]
+  [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r")
+	(sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))]
   ""
   "@
    sexb%? %0,%1%&
    sexb %0,%1
+   ldb.x%U1 %0,%1
    ldb.x%U1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,*,8")])
 
 
 (define_expand "extendqihi2"
@@ -1539,15 +1550,17 @@
 )
 
 (define_insn "*extendqisi2_ac"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
-	(sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
+	(sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
   ""
   "@
    sexb%? %0,%1%&
    sexb %0,%1
+   ldb.x%U1 %0,%1
    ldb.x%U1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,*,8")])
 
 (define_expand "extendqisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
@@ -1557,15 +1570,17 @@
 )
 
 (define_insn "*extendhisi2_i"
-  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r")
-	(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))]
+  [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r")
+	(sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))]
   ""
   "@
    sex%_%? %0,%1%&
    sex%_ %0,%1
+   ld%_.x%U1%V1 %0,%1
    ld%_.x%U1%V1 %0,%1"
-  [(set_attr "type" "unary,unary,load")
-   (set_attr "iscompact" "true,false,false")])
+  [(set_attr "type" "unary,unary,load,load")
+   (set_attr "iscompact" "true,false,false,false")
+   (set_attr "length" "*,*,4,8")])
 
 (define_expand "extendhisi2"
   [(set (match_operand:SI 0 "dest_reg_operand" "")
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 14fd2a4..19d4c21 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -462,3 +462,11 @@ Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD)
 
 EnumValue
 Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD)
+
+mcmem
+Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT)
+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.
diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md
index b6954ad..c2992c9 100644
--- a/gcc/config/arc/constraints.md
+++ b/gcc/config/arc/constraints.md
@@ -269,6 +269,13 @@
   (and (match_code "mem")
        (match_test "compact_store_memory_operand (op, VOIDmode)")))
 
+(define_memory_constraint "Uex"
+  "@internal
+   A valid memory operand for limm-free extend instructions"
+  (and (match_code "mem")
+       (match_test "!cmem_address (XEXP (op, 0), SImode)")
+       (not (match_operand 0 "long_immediate_loadstore_operand"))))
+
 ; Don't use define_memory_constraint here as the relocation patching
 ; for small data symbols only works within a ld/st instruction and
 ; define_memory_constraint may result in the address being calculated
@@ -303,6 +310,12 @@
        (match_test "REG_P (XEXP (XEXP (op, 0), 0))")
        (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG")))
 
+(define_constraint "Ucm"
+  "@internal
+  cmem access"
+  (and (match_code "mem")
+       (match_test "TARGET_NPS_CMEM && cmem_address (XEXP (op, 0), VOIDmode)")))
+
 ;; General constraints
 
 (define_constraint "Cbr"
@@ -430,4 +443,3 @@
 (define_memory_constraint "ATO"
   "A memory with only a base register"
   (match_operand 0 "mem_noofs_operand"))
-
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index 85bbf84..91726db 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -123,6 +123,8 @@
   int size = GET_MODE_SIZE (GET_MODE (op));
 
   op = XEXP (op, 0);
+  if (TARGET_NPS_CMEM && cmem_address (op, SImode))
+    return 0;
   switch (GET_CODE (op))
     {
     case SYMBOL_REF :
@@ -806,3 +808,20 @@
 (define_predicate "double_register_operand"
   (ior (match_test "even_register_operand (op, mode)")
        (match_test "arc_double_register_operand (op, mode)")))
+
+(define_predicate "cmem_address_0"
+  (and (match_code "symbol_ref")
+       (match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_CMEM")))
+
+(define_predicate "cmem_address_1"
+  (and (match_code "plus")
+       (match_test "cmem_address_0 (XEXP (op, 0), SImode)")))
+
+(define_predicate "cmem_address_2"
+  (and (match_code "const")
+       (match_test "cmem_address_1 (XEXP (op, 0), SImode)")))
+
+(define_predicate "cmem_address"
+  (ior (match_operand:SI 0 "cmem_address_0")
+       (match_operand:SI 0 "cmem_address_1")
+       (match_operand:SI 0 "cmem_address_2")))
diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c b/gcc/testsuite/gcc.target/arc/cmem-1.c
new file mode 100644
index 0000000..7f36afb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c b/gcc/testsuite/gcc.target/arc/cmem-2.c
new file mode 100644
index 0000000..a3d7c130
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c b/gcc/testsuite/gcc.target/arc/cmem-3.c
new file mode 100644
index 0000000..dee73b5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c b/gcc/testsuite/gcc.target/arc/cmem-4.c
new file mode 100644
index 0000000..1da6bce
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-4.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c b/gcc/testsuite/gcc.target/arc/cmem-5.c
new file mode 100644
index 0000000..ad6904f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-5.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
+
+#include "cmem-st.inc"
+
+/* { dg-final { scan-assembler "xst " } } */
+/* { dg-final { scan-assembler "xstw " } } */
+/* { dg-final { scan-assembler "xstb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c b/gcc/testsuite/gcc.target/arc/cmem-6.c
new file mode 100644
index 0000000..24bc39b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-6.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared")));
+
+#include "cmem-ld.inc"
+
+/* { dg-final { scan-assembler "xld " } } */
+/* { dg-final { scan-assembler "xldw " } } */
+/* { dg-final { scan-assembler "xldb " } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c b/gcc/testsuite/gcc.target/arc/cmem-7.c
new file mode 100644
index 0000000..72ee7bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-7.c
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-mcpu=nps400 -mcmem" } */
+
+struct some_struct
+{
+  unsigned char a;
+};
+
+unsigned char other_func (unsigned char);
+
+unsigned char
+some_function ()
+{
+  static struct some_struct ss __attribute__ ((section (".cmem")));
+  static struct some_struct tt;
+
+  ss.a = other_func (ss.a);
+  tt.a = other_func (tt.a);
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler "xldb \[^\n\]*@ss" } } */
+/* { dg-final { scan-assembler "xstb \[^\n\]*@ss" } } */
+/* { dg-final { scan-assembler-not "xldb \[^\n\]*@tt" } } */
+/* { dg-final { scan-assembler-not "xstb \[^\n\]*@tt" } } */
diff --git a/gcc/testsuite/gcc.target/arc/cmem-ld.inc b/gcc/testsuite/gcc.target/arc/cmem-ld.inc
new file mode 100644
index 0000000..7b51bb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-ld.inc
@@ -0,0 +1,16 @@
+
+struct foo_type
+{
+  unsigned int a;
+  unsigned short b;
+  unsigned char c;
+};
+
+struct foo_type foo __attribute__ ((section (".cmem")));
+
+unsigned int
+f ()
+{
+  unsigned int tmp = foo.a + foo.b + foo.c;
+  return tmp;
+}
diff --git a/gcc/testsuite/gcc.target/arc/cmem-st.inc b/gcc/testsuite/gcc.target/arc/cmem-st.inc
new file mode 100644
index 0000000..30aeace
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cmem-st.inc
@@ -0,0 +1,18 @@
+
+struct foo_type
+{
+  unsigned int a;
+  unsigned short b;
+  unsigned char c;
+};
+
+struct foo_type foo CMEM_SECTION_ATTR
+
+int
+f ()
+{
+  foo.a = 3;
+  foo.b = 2;
+  foo.c = 1;
+  return 0;
+}
-- 
2.6.4

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

* [PATCHv2 1/7] gcc/arc: Add support for nps400 cpu type.
  2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
                   ` (16 preceding siblings ...)
  2016-04-21 11:40 ` [PATCHv2 6/7] gcc/arc: Mask integer 'L' operands to 32-bit Andrew Burgess
@ 2016-04-21 11:40 ` Andrew Burgess
  2016-04-28 17:07   ` Joern Wolfgang Rennecke
  17 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-21 11:40 UTC (permalink / raw)
  To: gcc-patches, gnu; +Cc: noamca, Claudiu.Zissulescu, Andrew Burgess

The nps400 is an arc700 with a set of extension instructions produced by
Mellanox (formally EZChip).  This commit adds support for the nps400
architecture to the arc backend.

After this commit it is possible to compile using -mcpu=nps400 in order
to specialise for the nps400.  Later commits add support for the
specific extension instructions.

gcc/ChangeLog:

	* common/config/arc/arc-common.c (arc_handle_option): Add NPS400
	support, setup defaults.
	* config/arc/arc-opts.h (enum processor_type): Add NPS400.
	* config/arc/arc.c (arc_init): Add NPS400 support.
	* config/arc/arc.h (CPP_SPEC): Add NPS400 defines.
	(TARGET_ARC700): NPS400 is also an ARC700.
	* config/arc/arc.opt: Add NPS400 options to -mcpu=.
---
 gcc/ChangeLog.NPS400               | 9 +++++++++
 gcc/common/config/arc/arc-common.c | 4 ++++
 gcc/config/arc/arc-opts.h          | 1 +
 gcc/config/arc/arc.c               | 5 +++++
 gcc/config/arc/arc.h               | 5 ++++-
 gcc/config/arc/arc.opt             | 6 ++++++
 6 files changed, 29 insertions(+), 1 deletion(-)
 create mode 100644 gcc/ChangeLog.NPS400

diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c
index 64fb053..f5b9c6d 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -83,6 +83,10 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set,
 
       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) )
diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h
index 1e11ebc4..cbd7898 100644
--- a/gcc/config/arc/arc-opts.h
+++ b/gcc/config/arc/arc-opts.h
@@ -24,6 +24,7 @@ enum processor_type
   PROCESSOR_ARC600,
   PROCESSOR_ARC601,
   PROCESSOR_ARC700,
+  PROCESSOR_NPS400,
   PROCESSOR_ARCEM,
   PROCESSOR_ARCHS
 };
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index d60db50..ae8772e 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -649,6 +649,11 @@ arc_init (void)
       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;
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index 1c2a38d..f96bf0f 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -136,6 +136,8 @@ 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__} \
 "
 
 #define CC1_SPEC "\
@@ -297,7 +299,8 @@ along with GCC; see the file COPYING3.  If not see
 
 #define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600)
 #define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601)
-#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700)
+#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							\
diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt
index 2227b75..14fd2a4 100644
--- a/gcc/config/arc/arc.opt
+++ b/gcc/config/arc/arc.opt
@@ -189,6 +189,12 @@ 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
-- 
2.6.4

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

* Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-04-21 11:39 ` [PATCHv2 0/7] ARC: Add support for nps400 variant Andrew Burgess
@ 2016-04-28 15:31   ` Joern Wolfgang Rennecke
  2016-04-28 16:55     ` Joern Wolfgang Rennecke
  0 siblings, 1 reply; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 15:31 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu



On 21/04/16 12:39, Andrew Burgess wrote:
> This new iteration of the previous version is largely the same except
> that I now no longer use configure time options to build in support
> for nps400.  Instead support controlled with a -mcpu=nps400 command
> line switch.  This change was made to mirror a similar change that was
> requested when I pushed nps400 support upstream into binutils.
The considerations for these toolchain components are different;
it costs little to have do a build with support for an entire architecture
with various variants in binutils.
gcc having run-time options to generate code for a subtarget is
also useful.
However, setting defaults and multilib sets at gcc configure time is
also quite useful, as otherwise every user is confronted with building
multilibs for a burgeoning array of variants.

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

* Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-04-28 15:31   ` Joern Wolfgang Rennecke
@ 2016-04-28 16:55     ` Joern Wolfgang Rennecke
  2016-04-29  9:04       ` Claudiu Zissulescu
  0 siblings, 1 reply; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 16:55 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu



On 28/04/16 16:31, Joern Wolfgang Rennecke wrote:
>
> However, setting defaults and multilib sets at gcc configure time is
> also quite useful, as otherwise every user is confronted with building
> multilibs for a burgeoning array of variants.
P.S.: One way to do this is to add introduce a new macro 
SUBTARGET_SELF_SPECS,
to augment DRIVER_SELF_SPECS, and use config.gcc to set this in 
tm_defines to

"%{!mcpu:-mcpu=nps400}" for this subtarget

to set the default cpu.



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

* Re: [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns
  2016-04-21 11:39 ` [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns Andrew Burgess
@ 2016-04-28 17:07   ` Joern Wolfgang Rennecke
  2016-04-29 11:59     ` Andrew Burgess
  0 siblings, 1 reply; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 17:07 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu



On 21/04/16 12:39, Andrew Burgess wrote:
>   
>
> 	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
> 	constraint with separate 'r' and 'Cm2' constraints.
> 	
Why don't you use simply rCm2 ?

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

* Re: [PATCHv2 1/7] gcc/arc: Add support for nps400 cpu type.
  2016-04-21 11:40 ` [PATCHv2 1/7] gcc/arc: Add support for nps400 cpu type Andrew Burgess
@ 2016-04-28 17:07   ` Joern Wolfgang Rennecke
  0 siblings, 0 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 17:07 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu



On 21/04/16 12:39, Andrew Burgess wrote:
> The nps400 is an arc700 with a set of extension instructions produced by
> Mellanox (formally EZChip).  This commit adds support for the nps400
> architecture to the arc backend.
>
> After this commit it is possible to compile using -mcpu=nps400 in order
> to specialise for the nps400.  Later commits add support for the
> specific extension instructions.
>
> gcc/ChangeLog:
>
> 	* common/config/arc/arc-common.c (arc_handle_option): Add NPS400
> 	support, setup defaults.
> 	* config/arc/arc-opts.h (enum processor_type): Add NPS400.
> 	* config/arc/arc.c (arc_init): Add NPS400 support.
> 	* config/arc/arc.h (CPP_SPEC): Add NPS400 defines.
> 	(TARGET_ARC700): NPS400 is also an ARC700.
> 	* config/arc/arc.opt: Add NPS400 options to -mcpu=.
Thanks.  I have applied this patch.

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

* Re: [PATCHv2 3/7] gcc/arc: convert some constraints to define_constraint
  2016-04-21 11:39 ` [PATCHv2 3/7] gcc/arc: convert some constraints to define_constraint Andrew Burgess
@ 2016-04-28 17:16   ` Joern Wolfgang Rennecke
  0 siblings, 0 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 17:16 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu



On 21/04/16 12:39, Andrew Burgess wrote:
> * config/arc/constraints.md (Usd): Convert to define_constraint.
> 	(Us<): Likewise.
> 	(Us>): Likewise.
Thanks.  I have allied this patch.

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

* Re: [PATCHv2 4/7] gcc/arc: Add support for nps400 cmem xld/xst instructions
  2016-04-21 11:40 ` [PATCHv2 4/7] gcc/arc: Add support for nps400 cmem xld/xst instructions Andrew Burgess
@ 2016-04-28 18:23   ` Joern Wolfgang Rennecke
  0 siblings, 0 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 18:23 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu

Thanks.  I have merged this patch.

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

* Re: [PATCHv2 5/7] gcc/arc: Add nps400 bitops support
  2016-04-21 11:40 ` [PATCHv2 5/7] gcc/arc: Add nps400 bitops support Andrew Burgess
@ 2016-04-28 18:50   ` Joern Wolfgang Rennecke
  0 siblings, 0 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 18:50 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu



On 21/04/16 12:39, Andrew Burgess wrote:
> Add support for nps400 bit operation instructions.  There's a new flag
> -mbitops that turns this feature on.  There are new instructions, some
> changes to existing instructions, a new register class to support the
> new instructions, and some new expand and peephole optimisations.
>
> gcc/ChangeLog:
>
> 	* config/arc/arc.c (arc_conditional_register_usage): Take
> 	TARGET_RRQ_CLASS into account.
> 	(arc_print_operand): Support printing 'p' and 's' operands.
> 	* config/arc/arc.h (TARGET_NPS_BITOPS_DEFAULT): Provide default
> 	as 0.
> 	(TARGET_RRQ_CLASS): Define.
> 	(IS_POWEROF2_OR_0_P): Define.
> 	* config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi
> 	alternatives.
> 	(*tst_movb): New define_insn.
> 	(*tst): Avoid recognition if it could prevent '*tst_movb'
> 	combination; replace c/CnL with c/Chs alternative.
> 	(*tst_bitfield_tst): New define_insn.
> 	(*tst_bitfield_asr): New define_insn.
> 	(*tst_bitfield): New define_insn.
> 	(andsi3_i): Add Rrq variant.
> 	(extzv): New define_expand.
> 	(insv): New define_expand.
> 	(*insv_i): New define_insn.
> 	(*movb): New define_insn.
> 	(*movb_signed): New define_insn.
> 	(*movb_high): New define_insn.
> 	(*movb_high_signed): New define_insn.
> 	(*movb_high_signed + 1): New define_split pattern.
> 	(*mrgb): New define_insn.
> 	(*mrgb + 1): New define_peephole2 pattern.
> 	(*mrgb + 2): New define_peephole2 pattern.
> 	* config/arc/arc.opt (mbitops): New option for nps400, uses
> 	TARGET_NPS_BITOPS_DEFAULT.
> 	* config/arc/constraints.md (q): Make register class conditional.
> 	(Rrq): New register constraint.
> 	(Chs): New constraint.
> 	(Clo): New constraint.
> 	(Chi): New constraint.
> 	(Cbf): New constraint.
> 	(Cbn): New constraint.
> 	(C18): New constraint.
> 	(Cbi): New constraint.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/arc/extzv-1.c: New file.
> 	* gcc.target/arc/insv-1.c: New file.
> 	* gcc.target/arc/insv-2.c: New file.
> 	* gcc.target/arc/movb-1.c: New file.
> 	* gcc.target/arc/movb-2.c: New file.
> 	* gcc.target/arc/movb-3.c: New file.
> 	* gcc.target/arc/movb-4.c: New file.
> 	* gcc.target/arc/movb-5.c: New file.
> 	* gcc.target/arc/movb_cl-1.c: New file.
> 	* gcc.target/arc/movb_cl-2.c: New file.
> 	* gcc.target/arc/movbi_cl-1.c: New file.
> 	* gcc.target/arc/movl-1.c: New file.
>
  Thanks.  I have applied this patch.

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

* Re: [PATCHv2 6/7] gcc/arc: Mask integer 'L' operands to 32-bit
  2016-04-21 11:40 ` [PATCHv2 6/7] gcc/arc: Mask integer 'L' operands to 32-bit Andrew Burgess
@ 2016-04-28 19:09   ` Joern Wolfgang Rennecke
  0 siblings, 0 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 19:09 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu

Thanks.  I have applied this patch.

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

* Re: [PATCHv2 7/7] gcc/arc: Add an nps400 specific testcase
  2016-04-21 11:40 ` [PATCHv2 7/7] gcc/arc: Add an nps400 specific testcase Andrew Burgess
@ 2016-04-28 19:14   ` Joern Wolfgang Rennecke
  0 siblings, 0 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-28 19:14 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches; +Cc: noamca, Claudiu.Zissulescu



On 21/04/16 12:39, Andrew Burgess wrote:
> * gcc.target/arc/nps400-1.c: New file.
Thanks.  I have applied this patch.

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

* RE: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-04-28 16:55     ` Joern Wolfgang Rennecke
@ 2016-04-29  9:04       ` Claudiu Zissulescu
  2016-04-29 10:22         ` Andrew Burgess
  2016-04-29 22:17         ` Andrew Burgess
  0 siblings, 2 replies; 46+ messages in thread
From: Claudiu Zissulescu @ 2016-04-29  9:04 UTC (permalink / raw)
  To: Joern Wolfgang Rennecke, Andrew Burgess, gcc-patches; +Cc: noamca

Hi Andrew,

I see the next tests failing:

FAIL: gcc.target/arc/movb-1.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *19, *21, *8
FAIL: gcc.target/arc/movb-2.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *23, *23, *9
FAIL: gcc.target/arc/movb-5.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *23, *(23|7), *9
FAIL: gcc.target/arc/movh_cl-1.c scan-assembler movh.cl r[0-9]+,0xc0000000>>16

Please can you confirm, and if it is the case please fix them.

Thanks,
Claudiu

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

* Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-04-29  9:04       ` Claudiu Zissulescu
@ 2016-04-29 10:22         ` Andrew Burgess
  2016-04-29 22:17         ` Andrew Burgess
  1 sibling, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-04-29 10:22 UTC (permalink / raw)
  To: Claudiu Zissulescu; +Cc: Joern Wolfgang Rennecke, gcc-patches, noamca

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-04-29 09:03:53 +0000]:

> I see the next tests failing:
> 
> FAIL: gcc.target/arc/movb-1.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *19, *21, *8
> FAIL: gcc.target/arc/movb-2.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *23, *23, *9
> FAIL: gcc.target/arc/movb-5.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *23, *(23|7), *9
> FAIL: gcc.target/arc/movh_cl-1.c scan-assembler movh.cl r[0-9]+,0xc0000000>>16
> 
> Please can you confirm, and if it is the case please fix them.

I will investigate these today.

Thanks,
Andrew

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

* Re: [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns
  2016-04-28 17:07   ` Joern Wolfgang Rennecke
@ 2016-04-29 11:59     ` Andrew Burgess
  2016-04-29 12:09       ` Joern Wolfgang Rennecke
  0 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-04-29 11:59 UTC (permalink / raw)
  To: Joern Wolfgang Rennecke; +Cc: gcc-patches, noamca, Claudiu.Zissulescu

* Joern Wolfgang Rennecke <gnu@amylaar.uk> [2016-04-28 18:06:42 +0100]:

> On 21/04/16 12:39, Andrew Burgess wrote:
> >
> >	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
> >	constraint with separate 'r' and 'Cm2' constraints.
> >	
> Why don't you use simply rCm2 ?

You are absolutely correct.  Thank you for pointing this out.

The much simpler version of this patch is below.

Thanks,
Andrew

---

gcc/arc: Replace rI constraint with rCm2 for ld and update insns

In the load*_update instructions the constraint 'rI' was being used,
which would accept either a register or a signed 12 bit constant.  The
problem is that the 32-bit form of ld with update only takes a signed
9-bit immediate.  As such, some ld instructions could be generated that
would, when assembled be 64-bit long, however, GCC believed them to be
32-bit long.  This error in the length would cause problems during
branch shortening.

The store*_update have the same restrictions on immediate size, however,
the patterns for these instructions already only accept 9-bit
immediates, and so should be safe.

gcc/ChangeLog:

	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
	constraint with 'rCm2' constraints to limit possible immediate
	size.
	(*load_zeroextendqisi_update): Likewise.
	(*load_signextendqisi_update): Likewise.
	(*loadhi_update): Likewise.
	(*load_zeroextendhisi_update): Likewise.
	(*load_signextendhisi_update): Likewise.
	(*loadsi_update): Likewise.
	(*loadsf_update): Likewise.
---
 gcc/ChangeLog.NPS400  | 12 ++++++++++++
 gcc/config/arc/arc.md | 16 ++++++++--------
 2 files changed, 20 insertions(+), 8 deletions(-)
 create mode 100644 gcc/ChangeLog.NPS400

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index d1a9159..c61107f 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -1254,7 +1254,7 @@
   [(set (match_operand:QI 3 "dest_reg_operand" "=r,r")
         (match_operator:QI 4 "any_mem_operand"
          [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-                   (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
+                   (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
@@ -1266,7 +1266,7 @@
   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
 	(zero_extend:SI (match_operator:QI 4 "any_mem_operand"
 			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
+			           (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
@@ -1278,7 +1278,7 @@
   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
 	(sign_extend:SI (match_operator:QI 4 "any_mem_operand"
 			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
+			           (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
@@ -1304,7 +1304,7 @@
   [(set (match_operand:HI 3 "dest_reg_operand" "=r,r")
 	(match_operator:HI 4 "any_mem_operand"
 	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
+	           (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
@@ -1316,7 +1316,7 @@
   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
 	(zero_extend:SI (match_operator:HI 4 "any_mem_operand"
 			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
+			           (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
    (set (match_operand:SI 0 "dest_reg_operand" "=r,r")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
@@ -1329,7 +1329,7 @@
   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
 	(sign_extend:SI (match_operator:HI 4 "any_mem_operand"
 			 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-			           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])))
+			           (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])))
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
@@ -1354,7 +1354,7 @@
   [(set (match_operand:SI 3 "dest_reg_operand" "=r,r")
 	(match_operator:SI 4 "any_mem_operand"
 	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
+	           (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
@@ -1378,7 +1378,7 @@
   [(set (match_operand:SF 3 "dest_reg_operand" "=r,r")
 	(match_operator:SF 4 "any_mem_operand"
 	 [(plus:SI (match_operand:SI 1 "register_operand" "0,0")
-	           (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))
+	           (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))
    (set (match_operand:SI 0 "dest_reg_operand" "=w,w")
 	(plus:SI (match_dup 1) (match_dup 2)))]
   ""
-- 
2.6.4

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

* Re: [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns
  2016-04-29 11:59     ` Andrew Burgess
@ 2016-04-29 12:09       ` Joern Wolfgang Rennecke
  0 siblings, 0 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-04-29 12:09 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, noamca, Claudiu.Zissulescu



On 29/04/16 12:58, Andrew Burgess wrote:
>
> 	* config/arc/arc.md (*loadqi_update): Replace use of 'rI'
> 	constraint with 'rCm2' constraints to limit possible immediate
> 	size.
> 	(*load_zeroextendqisi_update): Likewise.
> 	(*load_signextendqisi_update): Likewise.
> 	(*loadhi_update): Likewise.
> 	(*load_zeroextendhisi_update): Likewise.
> 	(*load_signextendhisi_update): Likewise.
> 	(*loadsi_update): Likewise.
> 	(*loadsf_update): Likewise.
Thanks.  I have checked this in.

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

* Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-04-29  9:04       ` Claudiu Zissulescu
  2016-04-29 10:22         ` Andrew Burgess
@ 2016-04-29 22:17         ` Andrew Burgess
  2016-05-02  9:02           ` Claudiu Zissulescu
  2016-11-16 11:44           ` [PATCHv2 0/7] ARC: Add support for nps400 variant Claudiu Zissulescu
  1 sibling, 2 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-04-29 22:17 UTC (permalink / raw)
  To: Claudiu Zissulescu, Joern Wolfgang Rennecke; +Cc: gcc-patches, noamca

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-04-29 09:03:53 +0000]:

> I see the next tests failing:
> 
> FAIL: gcc.target/arc/movb-1.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *19, *21, *8
> FAIL: gcc.target/arc/movb-2.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *23, *23, *9
> FAIL: gcc.target/arc/movb-5.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+, *r[0-5]+, *23, *(23|7), *9
> FAIL: gcc.target/arc/movh_cl-1.c scan-assembler movh.cl r[0-9]+,0xc0000000>>16

Claudiu, Joern,

I believe that the patch below should resolve the issues that you're
seeing for little endian arc tests.

It's mostly just updating the expected results, though one test needed
improving for l/e arc.

In the final test the layout used for bitfields within a struct on
little endian arc just happened to result in a movb (move bits) not
being generated when it could / should have been.  I've added a new
peephole2 case to catch this.

Thanks,
Andrew

---

gcc/arc: New peephole2 and little endian arc test fixes

Resolve some test failures introduced for little endian arc as a result
of the recent arc/nps400 additions.

There's a new peephole2 optimisation to merge together two zero_extracts
in order that the movb instruction can be used.

One of the test cases is extended so that the test does something
meaningful in both big and little endian arc mode.

Other tests have their expected results updated to reflect improvements
in other areas of GCC.

gcc/ChangeLog:

	* config/arc/arc.md (movb peephole2): New peephole2 to merge two
	zero_extract operations to allow a movb to occur.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/movb-1.c: Update little endian arc results.
	* gcc.target/arc/movb-2.c: Likewise.
	* gcc.target/arc/movb-5.c: Likewise.
	* gcc.target/arc/movh_cl-1.c: Extend test to cover little endian
	arc.
---
 gcc/ChangeLog                            |  5 +++++
 gcc/config/arc/arc.md                    | 14 ++++++++++++++
 gcc/testsuite/ChangeLog                  |  8 ++++++++
 gcc/testsuite/gcc.target/arc/movb-1.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-2.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-5.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++
 7 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index c61107f..0b92594 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -6144,6 +6144,20 @@
 		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
    (match_dup 1)])
 
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+        (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 1 "const_int_operand" "")
+			 (match_operand:SI 2 "const_int_operand" "")))
+   (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
+			 (match_dup 1)
+                         (match_dup 2))
+	(match_dup 0))]
+  "TARGET_NPS_BITOPS
+   && !reg_overlap_mentioned_p (operands[0], operands[3])"
+  [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
+        (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
+
 ;; include the arc-FPX instructions
 (include "fpx.md")
 
diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
index 65d4ba4..94d9f5f 100644
--- a/gcc/testsuite/gcc.target/arc/movb-1.c
+++ b/gcc/testsuite/gcc.target/arc/movb-1.c
@@ -10,4 +10,4 @@ f (void)
   bar.b = foo.b;
 }
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *3, *5, *8" { target arc-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
index 1ba9976..708f393 100644
--- a/gcc/testsuite/gcc.target/arc/movb-2.c
+++ b/gcc/testsuite/gcc.target/arc/movb-2.c
@@ -9,5 +9,5 @@ f (void)
 {
   bar.b = foo.b;
 }
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
index 9dbe8a1..d285888 100644
--- a/gcc/testsuite/gcc.target/arc/movb-5.c
+++ b/gcc/testsuite/gcc.target/arc/movb-5.c
@@ -9,5 +9,5 @@ f (void)
 {
   bar.b = foo.b;
 }
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
index 220cd9d..c643481 100644
--- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
+++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
@@ -10,6 +10,9 @@ struct thing
     {
       unsigned a : 1;
       unsigned b : 1;
+      unsigned c : 28;
+      unsigned d : 1;
+      unsigned e : 1;
     };
   };
 };
@@ -24,4 +27,12 @@ blah ()
   func (xx.raw);
 }
 
+void
+woof ()
+{
+  struct thing xx;
+  xx.d = xx.e = 1;
+  func (xx.raw);
+}
+
 /* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
-- 
2.6.4

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

* RE: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-04-29 22:17         ` Andrew Burgess
@ 2016-05-02  9:02           ` Claudiu Zissulescu
  2016-05-03 10:56             ` Andrew Burgess
  2016-11-16 11:44           ` [PATCHv2 0/7] ARC: Add support for nps400 variant Claudiu Zissulescu
  1 sibling, 1 reply; 46+ messages in thread
From: Claudiu Zissulescu @ 2016-05-02  9:02 UTC (permalink / raw)
  To: Andrew Burgess, Joern Wolfgang Rennecke; +Cc: gcc-patches, noamca

Please also consider to address also the following warnings introduced:

mainline/gcc/gcc/config/arc/arc.md:888: warning: source missing a mode?
mainline/gcc/gcc/config/arc/arc.md:906: warning: source missing a mode?
mainline/gcc/gcc/config/arc/arc.md:921: warning: source missing a mode?
mainline/gcc/gcc/config/arc/arc.md:6146: warning: source missing a mode?

Thanks,
Claudiu

> -----Original Message-----
> From: Andrew Burgess [mailto:andrew.burgess@embecosm.com]
> Sent: Saturday, April 30, 2016 12:17 AM
> To: Claudiu Zissulescu; Joern Wolfgang Rennecke
> Cc: gcc-patches@gcc.gnu.org; noamca@mellanox.com
> Subject: Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
> 
> * Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-04-29
> 09:03:53 +0000]:
> 
> > I see the next tests failing:
> >
> > FAIL: gcc.target/arc/movb-1.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+,
> *r[0-5]+, *19, *21, *8
> > FAIL: gcc.target/arc/movb-2.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+,
> *r[0-5]+, *23, *23, *9
> > FAIL: gcc.target/arc/movb-5.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+,
> *r[0-5]+, *23, *(23|7), *9
> > FAIL: gcc.target/arc/movh_cl-1.c scan-assembler movh.cl r[0-
> 9]+,0xc0000000>>16
> 
> Claudiu, Joern,
> 
> I believe that the patch below should resolve the issues that you're
> seeing for little endian arc tests.
> 
> It's mostly just updating the expected results, though one test needed
> improving for l/e arc.
> 
> In the final test the layout used for bitfields within a struct on
> little endian arc just happened to result in a movb (move bits) not
> being generated when it could / should have been.  I've added a new
> peephole2 case to catch this.
> 
> Thanks,
> Andrew
> 
> ---
> 
> gcc/arc: New peephole2 and little endian arc test fixes
> 
> Resolve some test failures introduced for little endian arc as a result
> of the recent arc/nps400 additions.
> 
> There's a new peephole2 optimisation to merge together two zero_extracts
> in order that the movb instruction can be used.
> 
> One of the test cases is extended so that the test does something
> meaningful in both big and little endian arc mode.
> 
> Other tests have their expected results updated to reflect improvements
> in other areas of GCC.
> 
> gcc/ChangeLog:
> 
> 	* config/arc/arc.md (movb peephole2): New peephole2 to merge
> two
> 	zero_extract operations to allow a movb to occur.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/arc/movb-1.c: Update little endian arc results.
> 	* gcc.target/arc/movb-2.c: Likewise.
> 	* gcc.target/arc/movb-5.c: Likewise.
> 	* gcc.target/arc/movh_cl-1.c: Extend test to cover little endian
> 	arc.
> ---
>  gcc/ChangeLog                            |  5 +++++
>  gcc/config/arc/arc.md                    | 14 ++++++++++++++
>  gcc/testsuite/ChangeLog                  |  8 ++++++++
>  gcc/testsuite/gcc.target/arc/movb-1.c    |  2 +-
>  gcc/testsuite/gcc.target/arc/movb-2.c    |  2 +-
>  gcc/testsuite/gcc.target/arc/movb-5.c    |  2 +-
>  gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++
>  7 files changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index c61107f..0b92594 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -6144,6 +6144,20 @@
>  		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup
> 7)))])
>     (match_dup 1)])
> 
> +(define_peephole2
> +  [(set (match_operand:SI 0 "register_operand" "")
> +        (zero_extract:SI (match_dup 0)
> +			 (match_operand:SI 1 "const_int_operand" "")
> +			 (match_operand:SI 2 "const_int_operand" "")))
> +   (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
> +			 (match_dup 1)
> +                         (match_dup 2))
> +	(match_dup 0))]
> +  "TARGET_NPS_BITOPS
> +   && !reg_overlap_mentioned_p (operands[0], operands[3])"
> +  [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
> +        (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
> +
>  ;; include the arc-FPX instructions
>  (include "fpx.md")
> 
> diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c
> b/gcc/testsuite/gcc.target/arc/movb-1.c
> index 65d4ba4..94d9f5f 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-1.c
> @@ -10,4 +10,4 @@ f (void)
>    bar.b = foo.b;
>  }
>  /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *5, *3, *8" { target arceb-*-* } } } */
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *19, *21, *8" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *3, *5, *8" { target arc-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c
> b/gcc/testsuite/gcc.target/arc/movb-2.c
> index 1ba9976..708f393 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-2.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-2.c
> @@ -9,5 +9,5 @@ f (void)
>  {
>    bar.b = foo.b;
>  }
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *23, *23, *9" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *7, *7, *9" { target arc-*-* } } } */
>  /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *0, *0, *9" { target arceb-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c
> b/gcc/testsuite/gcc.target/arc/movb-5.c
> index 9dbe8a1..d285888 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-5.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-5.c
> @@ -9,5 +9,5 @@ f (void)
>  {
>    bar.b = foo.b;
>  }
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *23, *(23|7), *9" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *7, *7, *9" { target arc-*-* } } } */
>  /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *0, *0, *9" { target arceb-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> index 220cd9d..c643481 100644
> --- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> @@ -10,6 +10,9 @@ struct thing
>      {
>        unsigned a : 1;
>        unsigned b : 1;
> +      unsigned c : 28;
> +      unsigned d : 1;
> +      unsigned e : 1;
>      };
>    };
>  };
> @@ -24,4 +27,12 @@ blah ()
>    func (xx.raw);
>  }
> 
> +void
> +woof ()
> +{
> +  struct thing xx;
> +  xx.d = xx.e = 1;
> +  func (xx.raw);
> +}
> +
>  /* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
> --
> 2.6.4

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

* Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-05-02  9:02           ` Claudiu Zissulescu
@ 2016-05-03 10:56             ` Andrew Burgess
  2016-05-12 11:30               ` Claudiu Zissulescu
  2016-06-14 18:46               ` Joern Wolfgang Rennecke
  0 siblings, 2 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-05-03 10:56 UTC (permalink / raw)
  To: Claudiu Zissulescu, Joern Wolfgang Rennecke; +Cc: gcc-patches, noamca

* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-05-02 09:02:16 +0000]:

> Please also consider to address also the following warnings introduced:
> 
> mainline/gcc/gcc/config/arc/arc.md:888: warning: source missing a mode?
> mainline/gcc/gcc/config/arc/arc.md:906: warning: source missing a mode?
> mainline/gcc/gcc/config/arc/arc.md:921: warning: source missing a mode?
> mainline/gcc/gcc/config/arc/arc.md:6146: warning: source missing a mode?
> 

Here's a revised fixup patch that includes addressing these 4
warnings.

Thanks,
Andrew

---

gcc/arc: New peephole2 and little endian arc test fixes

Resolve some test failures introduced for little endian arc as a result
of the recent arc/nps400 additions.

There's a new peephole2 optimisation to merge together two zero_extracts
in order that the movb instruction can be used.

Source operand modes filled in for 3 instruction patterns and a
peephole2 optimisation, to silence build warnings.

One of the test cases is extended so that the test does something
meaningful in both big and little endian arc mode.

Other tests have their expected results updated to reflect improvements
in other areas of GCC.

gcc/ChangeLog:

	* config/arc/arc.md (movb peephole2): New peephole2 to merge two
	zero_extract operations to allow a movb to occur.
	(*tst_bitfield_tst): Add mode to source operand.
	(*tst_bitfield_asr): Likewise.
	(*tst_bitfield): Likewise.
	(bitops peephole2): Likewise.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/movb-1.c: Update little endian arc results.
	* gcc.target/arc/movb-2.c: Likewise.
	* gcc.target/arc/movb-5.c: Likewise.
	* gcc.target/arc/movh_cl-1.c: Extend test to cover little endian
	arc.
---
 gcc/ChangeLog                            |  9 +++++++++
 gcc/config/arc/arc.md                    | 22 ++++++++++++++++++----
 gcc/testsuite/ChangeLog                  |  8 ++++++++
 gcc/testsuite/gcc.target/arc/movb-1.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-2.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-5.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++
 7 files changed, 49 insertions(+), 7 deletions(-)

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index c61107f..96c1e77 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -879,7 +879,7 @@
 ; since this is about constants, reload shouldn't care.
 (define_insn "*tst_bitfield_tst"
   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
-	(match_operator 4 "zn_compare_operator"
+	(match_operator:CC_ZN 4 "zn_compare_operator"
 	  [(zero_extract:SI
 	     (match_operand:SI 1 "register_operand"  "c")
 	     (match_operand:SI 2 "const_int_operand" "n")
@@ -897,7 +897,7 @@
 ; Likewise for asr.f.
 (define_insn "*tst_bitfield_asr"
   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
-	(match_operator 4 "zn_compare_operator"
+	(match_operator:CC_ZN 4 "zn_compare_operator"
 	  [(zero_extract:SI
 	     (match_operand:SI 1 "register_operand"  "c")
 	     (match_operand:SI 2 "const_int_operand" "n")
@@ -912,7 +912,7 @@
 
 (define_insn "*tst_bitfield"
   [(set (match_operand:CC_ZN 0 "cc_set_register" "")
-	(match_operator 5 "zn_compare_operator"
+	(match_operator:CC_ZN 5 "zn_compare_operator"
 	  [(zero_extract:SI
 	     (match_operand:SI 1 "register_operand" "%Rcqq,c,  c,Rrq,c")
 	     (match_operand:SI 2 "const_int_operand"    "N,N,  n,Cbn,n")
@@ -6128,7 +6128,7 @@
 	(zero_extract:SI (match_dup 1)
 			 (match_dup 2)
 			 (match_operand:SI 4 "const_int_operand" "")))
-   (set (match_dup 1) (match_operand 8))
+   (set (match_dup 1) (match_operand:SI 8))
    (set (zero_extract:SI (match_dup 0)
 			 (match_operand:SI 5 "const_int_operand" "")
 			 (match_operand:SI 6 "const_int_operand" ""))
@@ -6144,6 +6144,20 @@
 		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
    (match_dup 1)])
 
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+        (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 1 "const_int_operand" "")
+			 (match_operand:SI 2 "const_int_operand" "")))
+   (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
+			 (match_dup 1)
+                         (match_dup 2))
+	(match_dup 0))]
+  "TARGET_NPS_BITOPS
+   && !reg_overlap_mentioned_p (operands[0], operands[3])"
+  [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
+        (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
+
 ;; include the arc-FPX instructions
 (include "fpx.md")
 
diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
index 65d4ba4..94d9f5f 100644
--- a/gcc/testsuite/gcc.target/arc/movb-1.c
+++ b/gcc/testsuite/gcc.target/arc/movb-1.c
@@ -10,4 +10,4 @@ f (void)
   bar.b = foo.b;
 }
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *3, *5, *8" { target arc-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
index 1ba9976..708f393 100644
--- a/gcc/testsuite/gcc.target/arc/movb-2.c
+++ b/gcc/testsuite/gcc.target/arc/movb-2.c
@@ -9,5 +9,5 @@ f (void)
 {
   bar.b = foo.b;
 }
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
index 9dbe8a1..d285888 100644
--- a/gcc/testsuite/gcc.target/arc/movb-5.c
+++ b/gcc/testsuite/gcc.target/arc/movb-5.c
@@ -9,5 +9,5 @@ f (void)
 {
   bar.b = foo.b;
 }
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
index 220cd9d..c643481 100644
--- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
+++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
@@ -10,6 +10,9 @@ struct thing
     {
       unsigned a : 1;
       unsigned b : 1;
+      unsigned c : 28;
+      unsigned d : 1;
+      unsigned e : 1;
     };
   };
 };
@@ -24,4 +27,12 @@ blah ()
   func (xx.raw);
 }
 
+void
+woof ()
+{
+  struct thing xx;
+  xx.d = xx.e = 1;
+  func (xx.raw);
+}
+
 /* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
-- 
2.6.4

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

* Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-05-03 10:56             ` Andrew Burgess
@ 2016-05-12 11:30               ` Claudiu Zissulescu
  2016-06-14 18:46               ` Joern Wolfgang Rennecke
  1 sibling, 0 replies; 46+ messages in thread
From: Claudiu Zissulescu @ 2016-05-12 11:30 UTC (permalink / raw)
  To: Andrew Burgess, Claudiu Zissulescu, Joern Wolfgang Rennecke
  Cc: gcc-patches, noamca

On 03/05/16 12:56, Andrew Burgess wrote:
> * Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-05-02 09:02:16 +0000]:
>
>> Please also consider to address also the following warnings introduced:
>>
>> mainline/gcc/gcc/config/arc/arc.md:888: warning: source missing a mode?
>> mainline/gcc/gcc/config/arc/arc.md:906: warning: source missing a mode?
>> mainline/gcc/gcc/config/arc/arc.md:921: warning: source missing a mode?
>> mainline/gcc/gcc/config/arc/arc.md:6146: warning: source missing a mode?
>>
>
> Here's a revised fixup patch that includes addressing these 4
> warnings.
>
> Thanks,
> Andrew
>
> ---
>
> gcc/arc: New peephole2 and little endian arc test fixes
>
> Resolve some test failures introduced for little endian arc as a result
> of the recent arc/nps400 additions.
>
> There's a new peephole2 optimisation to merge together two zero_extracts
> in order that the movb instruction can be used.
>
> Source operand modes filled in for 3 instruction patterns and a
> peephole2 optimisation, to silence build warnings.
>
> One of the test cases is extended so that the test does something
> meaningful in both big and little endian arc mode.
>
> Other tests have their expected results updated to reflect improvements
> in other areas of GCC.
>
> gcc/ChangeLog:
>
> 	* config/arc/arc.md (movb peephole2): New peephole2 to merge two
> 	zero_extract operations to allow a movb to occur.
> 	(*tst_bitfield_tst): Add mode to source operand.
> 	(*tst_bitfield_asr): Likewise.
> 	(*tst_bitfield): Likewise.
> 	(bitops peephole2): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/arc/movb-1.c: Update little endian arc results.
> 	* gcc.target/arc/movb-2.c: Likewise.
> 	* gcc.target/arc/movb-5.c: Likewise.
> 	* gcc.target/arc/movh_cl-1.c: Extend test to cover little endian
> 	arc.
> ---
>   gcc/ChangeLog                            |  9 +++++++++
>   gcc/config/arc/arc.md                    | 22 ++++++++++++++++++----
>   gcc/testsuite/ChangeLog                  |  8 ++++++++
>   gcc/testsuite/gcc.target/arc/movb-1.c    |  2 +-
>   gcc/testsuite/gcc.target/arc/movb-2.c    |  2 +-
>   gcc/testsuite/gcc.target/arc/movb-5.c    |  2 +-
>   gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++
>   7 files changed, 49 insertions(+), 7 deletions(-)
>
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index c61107f..96c1e77 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -879,7 +879,7 @@
>   ; since this is about constants, reload shouldn't care.
>   (define_insn "*tst_bitfield_tst"
>     [(set (match_operand:CC_ZN 0 "cc_set_register" "")
> -	(match_operator 4 "zn_compare_operator"
> +	(match_operator:CC_ZN 4 "zn_compare_operator"
>   	  [(zero_extract:SI
>   	     (match_operand:SI 1 "register_operand"  "c")
>   	     (match_operand:SI 2 "const_int_operand" "n")
> @@ -897,7 +897,7 @@
>   ; Likewise for asr.f.
>   (define_insn "*tst_bitfield_asr"
>     [(set (match_operand:CC_ZN 0 "cc_set_register" "")
> -	(match_operator 4 "zn_compare_operator"
> +	(match_operator:CC_ZN 4 "zn_compare_operator"
>   	  [(zero_extract:SI
>   	     (match_operand:SI 1 "register_operand"  "c")
>   	     (match_operand:SI 2 "const_int_operand" "n")
> @@ -912,7 +912,7 @@
>
>   (define_insn "*tst_bitfield"
>     [(set (match_operand:CC_ZN 0 "cc_set_register" "")
> -	(match_operator 5 "zn_compare_operator"
> +	(match_operator:CC_ZN 5 "zn_compare_operator"
>   	  [(zero_extract:SI
>   	     (match_operand:SI 1 "register_operand" "%Rcqq,c,  c,Rrq,c")
>   	     (match_operand:SI 2 "const_int_operand"    "N,N,  n,Cbn,n")
> @@ -6128,7 +6128,7 @@
>   	(zero_extract:SI (match_dup 1)
>   			 (match_dup 2)
>   			 (match_operand:SI 4 "const_int_operand" "")))
> -   (set (match_dup 1) (match_operand 8))
> +   (set (match_dup 1) (match_operand:SI 8))
>      (set (zero_extract:SI (match_dup 0)
>   			 (match_operand:SI 5 "const_int_operand" "")
>   			 (match_operand:SI 6 "const_int_operand" ""))
> @@ -6144,6 +6144,20 @@
>   		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
>      (match_dup 1)])
>
> +(define_peephole2
> +  [(set (match_operand:SI 0 "register_operand" "")
> +        (zero_extract:SI (match_dup 0)
> +			 (match_operand:SI 1 "const_int_operand" "")
> +			 (match_operand:SI 2 "const_int_operand" "")))
> +   (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
> +			 (match_dup 1)
> +                         (match_dup 2))
> +	(match_dup 0))]
> +  "TARGET_NPS_BITOPS
> +   && !reg_overlap_mentioned_p (operands[0], operands[3])"
> +  [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
> +        (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
> +
>   ;; include the arc-FPX instructions
>   (include "fpx.md")
>
> diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
> index 65d4ba4..94d9f5f 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-1.c
> @@ -10,4 +10,4 @@ f (void)
>     bar.b = foo.b;
>   }
>   /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *3, *5, *8" { target arc-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
> index 1ba9976..708f393 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-2.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-2.c
> @@ -9,5 +9,5 @@ f (void)
>   {
>     bar.b = foo.b;
>   }
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
>   /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
> index 9dbe8a1..d285888 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-5.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-5.c
> @@ -9,5 +9,5 @@ f (void)
>   {
>     bar.b = foo.b;
>   }
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
>   /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> index 220cd9d..c643481 100644
> --- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> @@ -10,6 +10,9 @@ struct thing
>       {
>         unsigned a : 1;
>         unsigned b : 1;
> +      unsigned c : 28;
> +      unsigned d : 1;
> +      unsigned e : 1;
>       };
>     };
>   };
> @@ -24,4 +27,12 @@ blah ()
>     func (xx.raw);
>   }
>
> +void
> +woof ()
> +{
> +  struct thing xx;
> +  xx.d = xx.e = 1;
> +  func (xx.raw);
> +}
> +
>   /* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
>

It seems alright to me, but you need to get Joern approval on this,
Claudiu

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

* Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-05-03 10:56             ` Andrew Burgess
  2016-05-12 11:30               ` Claudiu Zissulescu
@ 2016-06-14 18:46               ` Joern Wolfgang Rennecke
  2016-06-14 23:38                 ` [PATCH 0/2] Arc fixes and genrecog warning fix Andrew Burgess
                                   ` (2 more replies)
  1 sibling, 3 replies; 46+ messages in thread
From: Joern Wolfgang Rennecke @ 2016-06-14 18:46 UTC (permalink / raw)
  To: Andrew Burgess, Claudiu Zissulescu; +Cc: gcc-patches, noamca



On 03/05/16 11:56, Andrew Burgess wrote:
> * Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-05-02 09:02:16 +0000]:
>
>> Please also consider to address also the following warnings introduced:
>>
>> mainline/gcc/gcc/config/arc/arc.md:888: warning: source missing a mode?
>> mainline/gcc/gcc/config/arc/arc.md:906: warning: source missing a mode?
>> mainline/gcc/gcc/config/arc/arc.md:921: warning: source missing a mode?
>> mainline/gcc/gcc/config/arc/arc.md:6146: warning: source missing a mode?
>>
> Here's a revised fixup patch that includes addressing these 4
> warnings.

This the the wrong approach.

zn_compare_operator is a special predicate that accepts CC_ZNmode as 
well as CC_Zmode.
The point is that some comparison uses need Z and N set, while other are 
OK with just Z.
Not accepting CC_Zmode would cause spurious recognition rejections.

A generator program complaining about a missing mode for an operand with 
a special predicate
is wrong.

from md.texi:
: Predicates written with @code{define_special_predicate} do not get any
: automatic mode checks, and are treated as having special mode handling
: by @command{genrecog}.

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

* [PATCH 1/2] gcc/arc: New peephole2 and little endian arc test fixes
  2016-06-14 18:46               ` Joern Wolfgang Rennecke
  2016-06-14 23:38                 ` [PATCH 0/2] Arc fixes and genrecog warning fix Andrew Burgess
  2016-06-14 23:38                 ` [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates Andrew Burgess
@ 2016-06-14 23:38                 ` Andrew Burgess
  2 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-06-14 23:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joern Wolfgang Rennecke, Andrew Burgess

Resolve some test failures introduced for little endian arc as a result
of the recent arc/nps400 additions.

There's a new peephole2 optimisation to merge together two zero_extracts
in order that the movb instruction can be used.

Source operand mode filled in for a peephole2 optimisation, to silence a
build warning.

One of the test cases is extended so that the test does something
meaningful in both big and little endian arc mode.

Other tests have their expected results updated to reflect improvements
in other areas of GCC.

gcc/ChangeLog:

	* config/arc/arc.md (movb peephole2): New peephole2 to merge two
	zero_extract operations to allow a movb to occur.
	(bitops peephole2): Add mode to source operand.

gcc/testsuite/ChangeLog:

	* gcc.target/arc/movb-1.c: Update little endian arc results.
	* gcc.target/arc/movb-2.c: Likewise.
	* gcc.target/arc/movb-5.c: Likewise.
	* gcc.target/arc/movh_cl-1.c: Extend test to cover little endian
	arc.
---
 gcc/ChangeLog                            |  6 ++++++
 gcc/config/arc/arc.md                    | 16 +++++++++++++++-
 gcc/testsuite/ChangeLog                  |  8 ++++++++
 gcc/testsuite/gcc.target/arc/movb-1.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-2.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-5.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++
 7 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index a4ee084..dc57e9b 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -6157,7 +6157,7 @@
 	(zero_extract:SI (match_dup 1)
 			 (match_dup 2)
 			 (match_operand:SI 4 "const_int_operand" "")))
-   (set (match_dup 1) (match_operand 8))
+   (set (match_dup 1) (match_operand:SI 8))
    (set (zero_extract:SI (match_dup 0)
 			 (match_operand:SI 5 "const_int_operand" "")
 			 (match_operand:SI 6 "const_int_operand" ""))
@@ -6173,6 +6173,20 @@
 		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))])
    (match_dup 1)])
 
+(define_peephole2
+  [(set (match_operand:SI 0 "register_operand" "")
+        (zero_extract:SI (match_dup 0)
+			 (match_operand:SI 1 "const_int_operand" "")
+			 (match_operand:SI 2 "const_int_operand" "")))
+   (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
+			 (match_dup 1)
+                         (match_dup 2))
+	(match_dup 0))]
+  "TARGET_NPS_BITOPS
+   && !reg_overlap_mentioned_p (operands[0], operands[3])"
+  [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
+        (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
+
 ;; include the arc-FPX instructions
 (include "fpx.md")
 
diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c
index 65d4ba4..94d9f5f 100644
--- a/gcc/testsuite/gcc.target/arc/movb-1.c
+++ b/gcc/testsuite/gcc.target/arc/movb-1.c
@@ -10,4 +10,4 @@ f (void)
   bar.b = foo.b;
 }
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *3, *5, *8" { target arc-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c
index 1ba9976..708f393 100644
--- a/gcc/testsuite/gcc.target/arc/movb-2.c
+++ b/gcc/testsuite/gcc.target/arc/movb-2.c
@@ -9,5 +9,5 @@ f (void)
 {
   bar.b = foo.b;
 }
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c
index 9dbe8a1..d285888 100644
--- a/gcc/testsuite/gcc.target/arc/movb-5.c
+++ b/gcc/testsuite/gcc.target/arc/movb-5.c
@@ -9,5 +9,5 @@ f (void)
 {
   bar.b = foo.b;
 }
-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */
+/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */
 /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
index 220cd9d..c643481 100644
--- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
+++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
@@ -10,6 +10,9 @@ struct thing
     {
       unsigned a : 1;
       unsigned b : 1;
+      unsigned c : 28;
+      unsigned d : 1;
+      unsigned e : 1;
     };
   };
 };
@@ -24,4 +27,12 @@ blah ()
   func (xx.raw);
 }
 
+void
+woof ()
+{
+  struct thing xx;
+  xx.d = xx.e = 1;
+  func (xx.raw);
+}
+
 /* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
-- 
2.6.4

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

* [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates
  2016-06-14 18:46               ` Joern Wolfgang Rennecke
  2016-06-14 23:38                 ` [PATCH 0/2] Arc fixes and genrecog warning fix Andrew Burgess
@ 2016-06-14 23:38                 ` Andrew Burgess
  2016-06-15 18:08                   ` Richard Sandiford
  2016-06-14 23:38                 ` [PATCH 1/2] gcc/arc: New peephole2 and little endian arc test fixes Andrew Burgess
  2 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-06-14 23:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joern Wolfgang Rennecke, Andrew Burgess

In md.texi it says:

  Predicates written with @code{define_special_predicate} do not get any
  automatic mode checks, and are treated as having special mode handling
  by @command{genrecog}.

However, in genrecog, when validating a SET pattern, if either the
source or destination is missing a mode then a warning is given, even if
there's a predicate defined with define_special_predicate.

This commit silences the warning for special predicates.

gcc/ChangeLog:

	* genrecog.c (validate_pattern): Don't warn about missing mode for
	define_special_predicate predicates.
Acked-by: Andrew Burgess <andrew.burgess@embecosm.com>
---
 gcc/ChangeLog  |  5 +++++
 gcc/genrecog.c | 22 +++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index a9f5a4a..7596552 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -674,9 +674,25 @@ validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
 		 && !CONST_WIDE_INT_P (src)
 		 && GET_CODE (src) != CALL)
 	  {
-	    const char *which;
-	    which = (dmode == VOIDmode ? "destination" : "source");
-	    message_at (info->loc, "warning: %s missing a mode?", which);
+	    const char *which_msg;
+	    rtx which;
+	    const char *pred_name;
+	    const struct pred_data *pred;
+
+	    which_msg = (dmode == VOIDmode ? "destination" : "source");
+	    which = (dmode == VOIDmode ? dest : src);
+	    pred_name = XSTR (which, 1);
+	    if (pred_name[0] != 0)
+	      {
+		pred = lookup_predicate (pred_name);
+		if (!pred)
+		  error_at (info->loc, "unknown predicate '%s'", pred_name);
+	      }
+	    else
+	      pred = 0;
+	    if (!pred || !pred->special)
+	      message_at (info->loc, "warning: %s missing a mode?",
+			  which_msg);
 	  }
 
 	if (dest != SET_DEST (pattern))
-- 
2.6.4

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

* [PATCH 0/2] Arc fixes and genrecog warning fix
  2016-06-14 18:46               ` Joern Wolfgang Rennecke
@ 2016-06-14 23:38                 ` Andrew Burgess
  2016-06-14 23:38                 ` [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates Andrew Burgess
  2016-06-14 23:38                 ` [PATCH 1/2] gcc/arc: New peephole2 and little endian arc test fixes Andrew Burgess
  2 siblings, 0 replies; 46+ messages in thread
From: Andrew Burgess @ 2016-06-14 23:38 UTC (permalink / raw)
  To: gcc-patches; +Cc: Joern Wolfgang Rennecke, Andrew Burgess

Joern,

Thanks for taking the time to review the previous patch.

I've revised the original fix-up patch to remove the addition of the
MODE in the zn_compare_operator case as you suggest, this is patch #1.

Patch #2 is an attempt to address you comment:

  A generator program complaining about a missing mode for an operand
  with a special predicate is wrong.

I'm hoping you'll review (and if you like it) merge patch #1.  I'd
appreciate you feedback on patch #2.  I can always repost patch #2 as
a top-level post to the mailing list if you think this is the right
fix, but should get a wider audience.

Thanks,
Andrew

---

Andrew Burgess (2):
  gcc/arc: New peephole2 and little endian arc test fixes
  gcc/genrecog: Don't warn for missing mode on special predicates

 gcc/ChangeLog                            | 11 +++++++++++
 gcc/config/arc/arc.md                    | 16 +++++++++++++++-
 gcc/genrecog.c                           | 22 +++++++++++++++++++---
 gcc/testsuite/ChangeLog                  |  8 ++++++++
 gcc/testsuite/gcc.target/arc/movb-1.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-2.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movb-5.c    |  2 +-
 gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++
 8 files changed, 67 insertions(+), 7 deletions(-)

-- 
2.6.4

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

* Re: [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates
  2016-06-14 23:38                 ` [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates Andrew Burgess
@ 2016-06-15 18:08                   ` Richard Sandiford
  2016-06-30 13:38                     ` Andrew Burgess
  0 siblings, 1 reply; 46+ messages in thread
From: Richard Sandiford @ 2016-06-15 18:08 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, Joern Wolfgang Rennecke

Andrew Burgess <andrew.burgess@embecosm.com> writes:
> In md.texi it says:
>
>   Predicates written with @code{define_special_predicate} do not get any
>   automatic mode checks, and are treated as having special mode handling
>   by @command{genrecog}.
>
> However, in genrecog, when validating a SET pattern, if either the
> source or destination is missing a mode then a warning is given, even if
> there's a predicate defined with define_special_predicate.
>
> This commit silences the warning for special predicates.
>
> gcc/ChangeLog:
>
> 	* genrecog.c (validate_pattern): Don't warn about missing mode for
> 	define_special_predicate predicates.
> Acked-by: Andrew Burgess <andrew.burgess@embecosm.com>
> ---
>  gcc/ChangeLog  |  5 +++++
>  gcc/genrecog.c | 22 +++++++++++++++++++---
>  2 files changed, 24 insertions(+), 3 deletions(-)
>
> diff --git a/gcc/genrecog.c b/gcc/genrecog.c
> index a9f5a4a..7596552 100644
> --- a/gcc/genrecog.c
> +++ b/gcc/genrecog.c
> @@ -674,9 +674,25 @@ validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
>  		 && !CONST_WIDE_INT_P (src)
>  		 && GET_CODE (src) != CALL)
>  	  {
> -	    const char *which;
> -	    which = (dmode == VOIDmode ? "destination" : "source");
> -	    message_at (info->loc, "warning: %s missing a mode?", which);
> +	    const char *which_msg;
> +	    rtx which;
> +	    const char *pred_name;
> +	    const struct pred_data *pred;
> +
> +	    which_msg = (dmode == VOIDmode ? "destination" : "source");
> +	    which = (dmode == VOIDmode ? dest : src);
> +	    pred_name = XSTR (which, 1);
> +	    if (pred_name[0] != 0)
> +	      {
> +		pred = lookup_predicate (pred_name);
> +		if (!pred)
> +		  error_at (info->loc, "unknown predicate '%s'", pred_name);
> +	      }
> +	    else
> +	      pred = 0;
> +	    if (!pred || !pred->special)
> +	      message_at (info->loc, "warning: %s missing a mode?",
> +			  which_msg);

There's no guarantee at this point that "which" is a match_operand.
Also, I think the earlier:

        /* The operands of a SET must have the same mode unless one
	   is VOIDmode.  */
        else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode)
	  error_at (info->loc, "mode mismatch in set: %smode vs %smode",
		    GET_MODE_NAME (dmode), GET_MODE_NAME (smode));

should be skipped for special predicates too.

How about generalising:

	/* The mode of an ADDRESS_OPERAND is the mode of the memory
	   reference, not the mode of the address.  */
	if (GET_CODE (src) == MATCH_OPERAND
	    && ! strcmp (XSTR (src, 1), "address_operand"))
	  ;

to:

	if (special_predicate_operand_p (src)
	    || special_predicate_operand_p (dest))
	  ;

with a new special_predicate_operand_p helper?  I don't think we should
duplicate the "unknown predicate" error here; the helper can just return
false for unknown predicates.

Thanks,
Richard

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

* Re: [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates
  2016-06-15 18:08                   ` Richard Sandiford
@ 2016-06-30 13:38                     ` Andrew Burgess
  2016-07-04  8:47                       ` Richard Sandiford
  0 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-06-30 13:38 UTC (permalink / raw)
  To: gcc-patches, Joern Wolfgang Rennecke, rdsandiford

* Richard Sandiford <rdsandiford@googlemail.com> [2016-06-15 19:07:56 +0100]:

> Andrew Burgess <andrew.burgess@embecosm.com> writes:
> > In md.texi it says:
> >
> >   Predicates written with @code{define_special_predicate} do not get any
> >   automatic mode checks, and are treated as having special mode handling
> >   by @command{genrecog}.
> >
> > However, in genrecog, when validating a SET pattern, if either the
> > source or destination is missing a mode then a warning is given, even if
> > there's a predicate defined with define_special_predicate.
> >
> > This commit silences the warning for special predicates.
> >
> > gcc/ChangeLog:
> >
> > 	* genrecog.c (validate_pattern): Don't warn about missing mode for
> > 	define_special_predicate predicates.
> > Acked-by: Andrew Burgess <andrew.burgess@embecosm.com>
> > ---
> >  gcc/ChangeLog  |  5 +++++
> >  gcc/genrecog.c | 22 +++++++++++++++++++---
> >  2 files changed, 24 insertions(+), 3 deletions(-)
> >
> > diff --git a/gcc/genrecog.c b/gcc/genrecog.c
> > index a9f5a4a..7596552 100644
> > --- a/gcc/genrecog.c
> > +++ b/gcc/genrecog.c
> > @@ -674,9 +674,25 @@ validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
> >  		 && !CONST_WIDE_INT_P (src)
> >  		 && GET_CODE (src) != CALL)
> >  	  {
> > -	    const char *which;
> > -	    which = (dmode == VOIDmode ? "destination" : "source");
> > -	    message_at (info->loc, "warning: %s missing a mode?", which);
> > +	    const char *which_msg;
> > +	    rtx which;
> > +	    const char *pred_name;
> > +	    const struct pred_data *pred;
> > +
> > +	    which_msg = (dmode == VOIDmode ? "destination" : "source");
> > +	    which = (dmode == VOIDmode ? dest : src);
> > +	    pred_name = XSTR (which, 1);
> > +	    if (pred_name[0] != 0)
> > +	      {
> > +		pred = lookup_predicate (pred_name);
> > +		if (!pred)
> > +		  error_at (info->loc, "unknown predicate '%s'", pred_name);
> > +	      }
> > +	    else
> > +	      pred = 0;
> > +	    if (!pred || !pred->special)
> > +	      message_at (info->loc, "warning: %s missing a mode?",
> > +			  which_msg);
> 
> There's no guarantee at this point that "which" is a match_operand.
> Also, I think the earlier:
> 
>         /* The operands of a SET must have the same mode unless one
> 	   is VOIDmode.  */
>         else if (dmode != VOIDmode && smode != VOIDmode && dmode != smode)
> 	  error_at (info->loc, "mode mismatch in set: %smode vs %smode",
> 		    GET_MODE_NAME (dmode), GET_MODE_NAME (smode));
> 
> should be skipped for special predicates too.
> 
> How about generalising:
> 
> 	/* The mode of an ADDRESS_OPERAND is the mode of the memory
> 	   reference, not the mode of the address.  */
> 	if (GET_CODE (src) == MATCH_OPERAND
> 	    && ! strcmp (XSTR (src, 1), "address_operand"))
> 	  ;
> 
> to:
> 
> 	if (special_predicate_operand_p (src)
> 	    || special_predicate_operand_p (dest))
> 	  ;
> 
> with a new special_predicate_operand_p helper?  I don't think we should
> duplicate the "unknown predicate" error here; the helper can just return
> false for unknown predicates.

Thanks for taking the time to review and provide feedback.  Sorry it
has take a while to get around to this patch again.

I've updated the patch inline with your feedback.  How's this?

Thanks,
Andrew

---

gcc/genrecog: Don't warn for missing mode on special predicates

In md.texi it says:

  Predicates written with @code{define_special_predicate} do not get any
  automatic mode checks, and are treated as having special mode handling
  by @command{genrecog}.

In genrecog, when validating a SET pattern, there is already a special
case for 'address_operand' which is a special predicate, however,
other special predicates fall through to the code which checks for
incorrect use of VOIDmode.

This commit adds a new function for detecting special predicates, and
then generalises the check in validate_pattern so that mode checking
is skipped for all special predicates.

gcc/ChangeLog:

	* genrecog.c (special_predicate_operand_p): New function.
	(predicate_name): Move function.
	(validate_pattern): Don't warn about missing mode for all
	define_special_predicate predicates.
---
 gcc/ChangeLog  |  7 +++++++
 gcc/genrecog.c | 50 +++++++++++++++++++++++++++++++++++---------------
 2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index a9f5a4a..7c56225 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -463,6 +463,38 @@ constraints_supported_in_insn_p (rtx insn)
 	   || GET_CODE (insn) == DEFINE_PEEPHOLE2);
 }
 
+/* Return the name of the predicate matched by MATCH_RTX.  */
+
+static const char *
+predicate_name (rtx match_rtx)
+{
+  if (GET_CODE (match_rtx) == MATCH_SCRATCH)
+    return "scratch_operand";
+  else
+    return XSTR (match_rtx, 1);
+}
+
+/* Return true if OPERAND is a MATCH_OPERAND using a special predicate
+   function.  */
+
+static bool
+special_predicate_operand_p (rtx operand)
+{
+  if (GET_CODE (operand) == MATCH_OPERAND)
+    {
+      const char *pred_name = predicate_name (operand);
+      if (pred_name[0] != 0)
+	{
+	  const struct pred_data *pred;
+
+	  pred = lookup_predicate (pred_name);
+	  return pred->special;
+	}
+    }
+
+  return false;
+}
+
 /* Check for various errors in PATTERN, which is part of INFO.
    SET is nonnull for a destination, and is the complete set pattern.
    SET_CODE is '=' for normal sets, and '+' within a context that
@@ -651,10 +683,9 @@ validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
 	dmode = GET_MODE (dest);
 	smode = GET_MODE (src);
 
-	/* The mode of an ADDRESS_OPERAND is the mode of the memory
-	   reference, not the mode of the address.  */
-	if (GET_CODE (src) == MATCH_OPERAND
-	    && ! strcmp (XSTR (src, 1), "address_operand"))
+	/* Mode checking is not performed for special predicates.  */
+	if (special_predicate_operand_p (src)
+	    || special_predicate_operand_p (dest))
 	  ;
 
         /* The operands of a SET must have the same mode unless one
@@ -3788,17 +3819,6 @@ operator < (const pattern_pos &e1, const pattern_pos &e2)
   return diff < 0;
 }
 
-/* Return the name of the predicate matched by MATCH_RTX.  */
-
-static const char *
-predicate_name (rtx match_rtx)
-{
-  if (GET_CODE (match_rtx) == MATCH_SCRATCH)
-    return "scratch_operand";
-  else
-    return XSTR (match_rtx, 1);
-}
-
 /* Add new decisions to S that check whether the rtx at position POS
    matches PATTERN.  Return the state that is reached in that case.
    TOP_PATTERN is the overall pattern, as passed to match_pattern_1.  */
-- 
2.4.11

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

* Re: [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates
  2016-06-30 13:38                     ` Andrew Burgess
@ 2016-07-04  8:47                       ` Richard Sandiford
  2016-07-06 19:43                         ` Andrew Burgess
  0 siblings, 1 reply; 46+ messages in thread
From: Richard Sandiford @ 2016-07-04  8:47 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, Joern Wolfgang Rennecke

Andrew Burgess <andrew.burgess@embecosm.com> writes:
> +/* Return true if OPERAND is a MATCH_OPERAND using a special predicate
> +   function.  */
> +
> +static bool
> +special_predicate_operand_p (rtx operand)
> +{
> +  if (GET_CODE (operand) == MATCH_OPERAND)
> +    {
> +      const char *pred_name = predicate_name (operand);
> +      if (pred_name[0] != 0)
> +	{
> +	  const struct pred_data *pred;
> +
> +	  pred = lookup_predicate (pred_name);
> +	  return pred->special;

Thanks for removing the duplicated error check for unknown predicates.
I think that error gets reported later though, so we should check for
null here:

      return pred && pred->special;

OK with that change, thanks.

Richard

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

* Re: [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates
  2016-07-04  8:47                       ` Richard Sandiford
@ 2016-07-06 19:43                         ` Andrew Burgess
  2016-07-13 22:19                           ` Jeff Law
  0 siblings, 1 reply; 46+ messages in thread
From: Andrew Burgess @ 2016-07-06 19:43 UTC (permalink / raw)
  To: gcc-patches, Joern Wolfgang Rennecke, richard.sandiford

* Richard Sandiford <richard.sandiford@arm.com> [2016-07-04 09:47:20 +0100]:

> Andrew Burgess <andrew.burgess@embecosm.com> writes:
> > +/* Return true if OPERAND is a MATCH_OPERAND using a special predicate
> > +   function.  */
> > +
> > +static bool
> > +special_predicate_operand_p (rtx operand)
> > +{
> > +  if (GET_CODE (operand) == MATCH_OPERAND)
> > +    {
> > +      const char *pred_name = predicate_name (operand);
> > +      if (pred_name[0] != 0)
> > +	{
> > +	  const struct pred_data *pred;
> > +
> > +	  pred = lookup_predicate (pred_name);
> > +	  return pred->special;
> 
> Thanks for removing the duplicated error check for unknown predicates.
> I think that error gets reported later though, so we should check for
> null here:
> 
>       return pred && pred->special;
> 
> OK with that change, thanks.

Richard,

Thanks for the continued reviews.  I don't have GCC write access, so I
wonder if you would be willing to commit this patch for me please.

There's an updated version below that includes the latest change you
suggested.

Many thanks,
Andrew

---

[PATCH] gcc/genrecog: Don't warn for missing mode on special predicates

In md.texi it says:

  Predicates written with @code{define_special_predicate} do not get any
  automatic mode checks, and are treated as having special mode handling
  by @command{genrecog}.

In genrecog, when validating a SET pattern, there is already a special
case for 'address_operand' which is a special predicate, however,
other special predicates fall through to the code which checks for
incorrect use of VOIDmode.

This commit adds a new function for detecting special predicates, and
then generalises the check in validate_pattern so that mode checking
is skipped for all special predicates.

gcc/ChangeLog:

	* genrecog.c (special_predicate_operand_p): New function.
	(predicate_name): Move function.
	(validate_pattern): Don't warn about missing mode for all
	define_special_predicate predicates.
---
 gcc/ChangeLog  |  7 +++++++
 gcc/genrecog.c | 50 +++++++++++++++++++++++++++++++++++---------------
 2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index a9f5a4a..056798c 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -463,6 +463,38 @@ constraints_supported_in_insn_p (rtx insn)
 	   || GET_CODE (insn) == DEFINE_PEEPHOLE2);
 }
 
+/* Return the name of the predicate matched by MATCH_RTX.  */
+
+static const char *
+predicate_name (rtx match_rtx)
+{
+  if (GET_CODE (match_rtx) == MATCH_SCRATCH)
+    return "scratch_operand";
+  else
+    return XSTR (match_rtx, 1);
+}
+
+/* Return true if OPERAND is a MATCH_OPERAND using a special predicate
+   function.  */
+
+static bool
+special_predicate_operand_p (rtx operand)
+{
+  if (GET_CODE (operand) == MATCH_OPERAND)
+    {
+      const char *pred_name = predicate_name (operand);
+      if (pred_name[0] != 0)
+	{
+	  const struct pred_data *pred;
+
+	  pred = lookup_predicate (pred_name);
+	  return pred != NULL && pred->special;
+	}
+    }
+
+  return false;
+}
+
 /* Check for various errors in PATTERN, which is part of INFO.
    SET is nonnull for a destination, and is the complete set pattern.
    SET_CODE is '=' for normal sets, and '+' within a context that
@@ -651,10 +683,9 @@ validate_pattern (rtx pattern, md_rtx_info *info, rtx set, int set_code)
 	dmode = GET_MODE (dest);
 	smode = GET_MODE (src);
 
-	/* The mode of an ADDRESS_OPERAND is the mode of the memory
-	   reference, not the mode of the address.  */
-	if (GET_CODE (src) == MATCH_OPERAND
-	    && ! strcmp (XSTR (src, 1), "address_operand"))
+	/* Mode checking is not performed for special predicates.  */
+	if (special_predicate_operand_p (src)
+	    || special_predicate_operand_p (dest))
 	  ;
 
         /* The operands of a SET must have the same mode unless one
@@ -3788,17 +3819,6 @@ operator < (const pattern_pos &e1, const pattern_pos &e2)
   return diff < 0;
 }
 
-/* Return the name of the predicate matched by MATCH_RTX.  */
-
-static const char *
-predicate_name (rtx match_rtx)
-{
-  if (GET_CODE (match_rtx) == MATCH_SCRATCH)
-    return "scratch_operand";
-  else
-    return XSTR (match_rtx, 1);
-}
-
 /* Add new decisions to S that check whether the rtx at position POS
    matches PATTERN.  Return the state that is reached in that case.
    TOP_PATTERN is the overall pattern, as passed to match_pattern_1.  */
-- 
2.5.1

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

* Re: [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates
  2016-07-06 19:43                         ` Andrew Burgess
@ 2016-07-13 22:19                           ` Jeff Law
  0 siblings, 0 replies; 46+ messages in thread
From: Jeff Law @ 2016-07-13 22:19 UTC (permalink / raw)
  To: Andrew Burgess, gcc-patches, Joern Wolfgang Rennecke, richard.sandiford

On 07/06/2016 01:42 PM, Andrew Burgess wrote:
> * Richard Sandiford <richard.sandiford@arm.com> [2016-07-04 09:47:20 +0100]:
>> Thanks for removing the duplicated error check for unknown predicates.
>> I think that error gets reported later though, so we should check for
>> null here:
>>
>>       return pred && pred->special;
>>
>> OK with that change, thanks.
>
> Richard,
>
> Thanks for the continued reviews.  I don't have GCC write access, so I
> wonder if you would be willing to commit this patch for me please.
>
> There's an updated version below that includes the latest change you
> suggested.
>
> Many thanks,
> Andrew
>
> ---
>
> [PATCH] gcc/genrecog: Don't warn for missing mode on special predicates
>
> In md.texi it says:
>
>   Predicates written with @code{define_special_predicate} do not get any
>   automatic mode checks, and are treated as having special mode handling
>   by @command{genrecog}.
>
> In genrecog, when validating a SET pattern, there is already a special
> case for 'address_operand' which is a special predicate, however,
> other special predicates fall through to the code which checks for
> incorrect use of VOIDmode.
>
> This commit adds a new function for detecting special predicates, and
> then generalises the check in validate_pattern so that mode checking
> is skipped for all special predicates.
>
> gcc/ChangeLog:
>
> 	* genrecog.c (special_predicate_operand_p): New function.
> 	(predicate_name): Move function.
> 	(validate_pattern): Don't warn about missing mode for all
> 	define_special_predicate predicates.
Committed.  THanks,

jeff

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

* RE: [PATCHv2 0/7] ARC: Add support for nps400 variant
  2016-04-29 22:17         ` Andrew Burgess
  2016-05-02  9:02           ` Claudiu Zissulescu
@ 2016-11-16 11:44           ` Claudiu Zissulescu
  1 sibling, 0 replies; 46+ messages in thread
From: Claudiu Zissulescu @ 2016-11-16 11:44 UTC (permalink / raw)
  To: Andrew Burgess; +Cc: gcc-patches, noamca, Francois Bedard

Approved and committed: Committed r24248

//Claudiu

> -----Original Message-----
> From: Andrew Burgess [mailto:andrew.burgess@embecosm.com]
> Sent: Saturday, April 30, 2016 12:17 AM
> To: Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com>; Joern Wolfgang
> Rennecke <gnu@amylaar.uk>
> Cc: gcc-patches@gcc.gnu.org; noamca@mellanox.com
> Subject: Re: [PATCHv2 0/7] ARC: Add support for nps400 variant
> 
> * Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2016-04-29
> 09:03:53 +0000]:
> 
> > I see the next tests failing:
> >
> > FAIL: gcc.target/arc/movb-1.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+,
> *r[0-5]+, *19, *21, *8
> > FAIL: gcc.target/arc/movb-2.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+,
> *r[0-5]+, *23, *23, *9
> > FAIL: gcc.target/arc/movb-5.c scan-assembler movb[ \t]+r[0-5]+, *r[0-5]+,
> *r[0-5]+, *23, *(23|7), *9
> > FAIL: gcc.target/arc/movh_cl-1.c scan-assembler movh.cl r[0-
> 9]+,0xc0000000>>16
> 
> Claudiu, Joern,
> 
> I believe that the patch below should resolve the issues that you're
> seeing for little endian arc tests.
> 
> It's mostly just updating the expected results, though one test needed
> improving for l/e arc.
> 
> In the final test the layout used for bitfields within a struct on
> little endian arc just happened to result in a movb (move bits) not
> being generated when it could / should have been.  I've added a new
> peephole2 case to catch this.
> 
> Thanks,
> Andrew
> 
> ---
> 
> gcc/arc: New peephole2 and little endian arc test fixes
> 
> Resolve some test failures introduced for little endian arc as a result
> of the recent arc/nps400 additions.
> 
> There's a new peephole2 optimisation to merge together two zero_extracts
> in order that the movb instruction can be used.
> 
> One of the test cases is extended so that the test does something
> meaningful in both big and little endian arc mode.
> 
> Other tests have their expected results updated to reflect improvements
> in other areas of GCC.
> 
> gcc/ChangeLog:
> 
> 	* config/arc/arc.md (movb peephole2): New peephole2 to merge
> two
> 	zero_extract operations to allow a movb to occur.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/arc/movb-1.c: Update little endian arc results.
> 	* gcc.target/arc/movb-2.c: Likewise.
> 	* gcc.target/arc/movb-5.c: Likewise.
> 	* gcc.target/arc/movh_cl-1.c: Extend test to cover little endian
> 	arc.
> ---
>  gcc/ChangeLog                            |  5 +++++
>  gcc/config/arc/arc.md                    | 14 ++++++++++++++
>  gcc/testsuite/ChangeLog                  |  8 ++++++++
>  gcc/testsuite/gcc.target/arc/movb-1.c    |  2 +-
>  gcc/testsuite/gcc.target/arc/movb-2.c    |  2 +-
>  gcc/testsuite/gcc.target/arc/movb-5.c    |  2 +-
>  gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++
>  7 files changed, 41 insertions(+), 3 deletions(-)
> 
> diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
> index c61107f..0b92594 100644
> --- a/gcc/config/arc/arc.md
> +++ b/gcc/config/arc/arc.md
> @@ -6144,6 +6144,20 @@
>  		   (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup
> 7)))])
>     (match_dup 1)])
> 
> +(define_peephole2
> +  [(set (match_operand:SI 0 "register_operand" "")
> +        (zero_extract:SI (match_dup 0)
> +			 (match_operand:SI 1 "const_int_operand" "")
> +			 (match_operand:SI 2 "const_int_operand" "")))
> +   (set (zero_extract:SI (match_operand:SI 3 "register_operand" "")
> +			 (match_dup 1)
> +                         (match_dup 2))
> +	(match_dup 0))]
> +  "TARGET_NPS_BITOPS
> +   && !reg_overlap_mentioned_p (operands[0], operands[3])"
> +  [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2))
> +        (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))])
> +
>  ;; include the arc-FPX instructions
>  (include "fpx.md")
> 
> diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c
> b/gcc/testsuite/gcc.target/arc/movb-1.c
> index 65d4ba4..94d9f5f 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-1.c
> @@ -10,4 +10,4 @@ f (void)
>    bar.b = foo.b;
>  }
>  /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *5, *3, *8" { target arceb-*-* } } } */
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *19, *21, *8" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *3, *5, *8" { target arc-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c
> b/gcc/testsuite/gcc.target/arc/movb-2.c
> index 1ba9976..708f393 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-2.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-2.c
> @@ -9,5 +9,5 @@ f (void)
>  {
>    bar.b = foo.b;
>  }
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *23, *23, *9" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *7, *7, *9" { target arc-*-* } } } */
>  /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *0, *0, *9" { target arceb-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c
> b/gcc/testsuite/gcc.target/arc/movb-5.c
> index 9dbe8a1..d285888 100644
> --- a/gcc/testsuite/gcc.target/arc/movb-5.c
> +++ b/gcc/testsuite/gcc.target/arc/movb-5.c
> @@ -9,5 +9,5 @@ f (void)
>  {
>    bar.b = foo.b;
>  }
> -/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *23, *(23|7), *9" { target arc-*-* } } } */
> +/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *7, *7, *9" { target arc-*-* } } } */
>  /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+,
> *0, *0, *9" { target arceb-*-* } } } */
> diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> index 220cd9d..c643481 100644
> --- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> +++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c
> @@ -10,6 +10,9 @@ struct thing
>      {
>        unsigned a : 1;
>        unsigned b : 1;
> +      unsigned c : 28;
> +      unsigned d : 1;
> +      unsigned e : 1;
>      };
>    };
>  };
> @@ -24,4 +27,12 @@ blah ()
>    func (xx.raw);
>  }
> 
> +void
> +woof ()
> +{
> +  struct thing xx;
> +  xx.d = xx.e = 1;
> +  func (xx.raw);
> +}
> +
>  /* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */
> --
> 2.6.4

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

end of thread, other threads:[~2016-11-16 11:44 UTC | newest]

Thread overview: 46+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-04 13:25 [PATCH 00/10] ARC: Add support for NPS400 variant Andrew Burgess
2016-03-04 13:25 ` [PATCH 01/10] gcc: Add support for mellanox nps400 arc variant Andrew Burgess
2016-03-04 13:26 ` [PATCH 04/10] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns Andrew Burgess
2016-03-04 13:26 ` [PATCH 09/10] gcc/arc: Add an nps400 specific testcase Andrew Burgess
2016-03-04 13:26 ` [PATCH 08/10] gcc/arc: Mask integer 'L' operands to 32-bit Andrew Burgess
2016-03-04 13:26 ` [PATCH 03/10] gcc/arc: generate jump tables in code section for nps400 Andrew Burgess
2016-03-04 13:26 ` [PATCH 05/10] gcc/arc: convert some constraints to define_constraint Andrew Burgess
2016-03-04 13:26 ` [PATCH 06/10] gcc/arc: Add support for nps400 cmem xld/xst instructions Andrew Burgess
2016-03-04 13:26 ` [PATCH 10/10] gcc/arc: Add __NPS400__ define for nps400 targets Andrew Burgess
2016-03-04 13:26 ` [PATCH 07/10] gcc/arc: Add nps400 bitops support Andrew Burgess
2016-03-04 13:26 ` [PATCH 02/10] gcc/arc: Add -munaligned-access option for nps400 Andrew Burgess
2016-04-21 11:39 ` [PATCHv2 3/7] gcc/arc: convert some constraints to define_constraint Andrew Burgess
2016-04-28 17:16   ` Joern Wolfgang Rennecke
2016-04-21 11:39 ` [PATCHv2 0/7] ARC: Add support for nps400 variant Andrew Burgess
2016-04-28 15:31   ` Joern Wolfgang Rennecke
2016-04-28 16:55     ` Joern Wolfgang Rennecke
2016-04-29  9:04       ` Claudiu Zissulescu
2016-04-29 10:22         ` Andrew Burgess
2016-04-29 22:17         ` Andrew Burgess
2016-05-02  9:02           ` Claudiu Zissulescu
2016-05-03 10:56             ` Andrew Burgess
2016-05-12 11:30               ` Claudiu Zissulescu
2016-06-14 18:46               ` Joern Wolfgang Rennecke
2016-06-14 23:38                 ` [PATCH 0/2] Arc fixes and genrecog warning fix Andrew Burgess
2016-06-14 23:38                 ` [PATCH 2/2] gcc/genrecog: Don't warn for missing mode on special predicates Andrew Burgess
2016-06-15 18:08                   ` Richard Sandiford
2016-06-30 13:38                     ` Andrew Burgess
2016-07-04  8:47                       ` Richard Sandiford
2016-07-06 19:43                         ` Andrew Burgess
2016-07-13 22:19                           ` Jeff Law
2016-06-14 23:38                 ` [PATCH 1/2] gcc/arc: New peephole2 and little endian arc test fixes Andrew Burgess
2016-11-16 11:44           ` [PATCHv2 0/7] ARC: Add support for nps400 variant Claudiu Zissulescu
2016-04-21 11:39 ` [PATCHv2 2/7] gcc/arc: Replace rI constraint with r & Cm2 for ld and update insns Andrew Burgess
2016-04-28 17:07   ` Joern Wolfgang Rennecke
2016-04-29 11:59     ` Andrew Burgess
2016-04-29 12:09       ` Joern Wolfgang Rennecke
2016-04-21 11:40 ` [PATCHv2 5/7] gcc/arc: Add nps400 bitops support Andrew Burgess
2016-04-28 18:50   ` Joern Wolfgang Rennecke
2016-04-21 11:40 ` [PATCHv2 7/7] gcc/arc: Add an nps400 specific testcase Andrew Burgess
2016-04-28 19:14   ` Joern Wolfgang Rennecke
2016-04-21 11:40 ` [PATCHv2 4/7] gcc/arc: Add support for nps400 cmem xld/xst instructions Andrew Burgess
2016-04-28 18:23   ` Joern Wolfgang Rennecke
2016-04-21 11:40 ` [PATCHv2 6/7] gcc/arc: Mask integer 'L' operands to 32-bit Andrew Burgess
2016-04-28 19:09   ` Joern Wolfgang Rennecke
2016-04-21 11:40 ` [PATCHv2 1/7] gcc/arc: Add support for nps400 cpu type Andrew Burgess
2016-04-28 17:07   ` Joern Wolfgang Rennecke

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).